├── .gitignore
├── CHANGE-LOG.md
├── LICENSE.txt
├── README.md
├── apache-client
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── litesuits
│ │ └── http
│ │ └── impl
│ │ └── apache
│ │ ├── ApacheClient.java
│ │ ├── DefaultHttpRequestRetryHandler.java
│ │ ├── EntityBuilder.java
│ │ ├── GZIPEntityWrapper.java
│ │ ├── HttpPatch.java
│ │ ├── HttpRetryHandler.java
│ │ ├── MyLayeredSocketFactory.java
│ │ ├── MySSLSocketFactory.java
│ │ ├── NotThreadSafe.java
│ │ ├── StandardHttpRequestRetryHandler.java
│ │ ├── TrustSSLSocketFactory.java
│ │ └── entity
│ │ ├── AbstractHttpEntity.java
│ │ ├── FileEntity.java
│ │ ├── InputStreamEntity.java
│ │ └── MultipartEntity.java
│ └── res
│ └── values
│ └── strings.xml
├── build.gradle
├── docs
├── 1-first-use.md
├── 2-async-request.md
├── lite-http-0-大纲.md
├── lite-http-1-初始化和初步使用.md
├── lite-http-10-异步并发与调度策略.md
├── lite-http-11-全局配置与参数设置详解.md
├── lite-http-12-通过注解完成API请求.md
├── lite-http-13-多层缓存机制及用法.md
├── lite-http-14-回调监听器详解.md
├── lite-http-15-并发调度控制器详解.md
├── lite-http-2-简化请求和非安全方法的使用.md
├── lite-http-3-自动对象转化.md
├── lite-http-4-自定义DataParser和Json序列化库的替换.md
├── lite-http-5-文件、位图的上传和下载.md
├── lite-http-6-禁用网络和流量&耗时统计.md
├── lite-http-7-重试和重定向.md
├── lite-http-8-处理异常和取消请求.md
├── lite-http-9-POST方式的多种类型数据传输.md
└── lite-http-引言.md
├── downloads
├── gson-2.3.jar
├── lite-go-1.0.0.jar
├── lite-http-3.0.0.jar
├── lite-http-3.0.1.jar
├── lite-http-3.1.3.6.jar
└── 并发需要依赖lite-go组件.md
├── gradle
└── wrapper
│ └── gradle-wrapper.jar
├── gradlew
├── gradlew.bat
├── litehttp-sample
├── .gitignore
├── build.gradle
├── libs
│ └── fastjson-1.2.5.jar
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── litesuits
│ │ └── http
│ │ └── sample
│ │ └── ApplicationTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── litesuits
│ │ │ └── http
│ │ │ ├── custom
│ │ │ ├── CustomJSONParser.java
│ │ │ ├── FastJson.java
│ │ │ └── MyHttpExceptHandler.java
│ │ │ ├── model
│ │ │ ├── ApiModel.java
│ │ │ ├── BaseModel.java
│ │ │ ├── User.java
│ │ │ └── api
│ │ │ │ ├── RichParam.java
│ │ │ │ └── UserParam.java
│ │ │ └── sample
│ │ │ ├── MainActivity.java
│ │ │ └── Test.java
│ └── res
│ │ ├── drawable
│ │ └── selector_list_item.xml
│ │ ├── layout
│ │ ├── activity_main.xml
│ │ └── list_item.xml
│ │ ├── mipmap-xxhdpi
│ │ └── ic_launcher.png
│ │ ├── values-zh
│ │ └── strings.xml
│ │ └── values
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── litesuits
│ └── http
│ └── sample
│ └── ExampleUnitTest.java
├── litehttp
├── .gitignore
├── build.gradle
├── libs
│ ├── fastjson-1.2.5.jar
│ ├── gson-2.3.jar
│ ├── lite-go-1.0.0.jar
│ └── lite-http-3.1.3.5.jar
├── proguard-rules.pro
└── src
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── litesuits
│ │ │ └── http
│ │ │ ├── HttpCache.java
│ │ │ ├── HttpClient.java
│ │ │ ├── HttpConfig.java
│ │ │ ├── LiteHttp.java
│ │ │ ├── annotation
│ │ │ ├── HttpBaseUrl.java
│ │ │ ├── HttpCacheExpire.java
│ │ │ ├── HttpCacheKey.java
│ │ │ ├── HttpCacheMode.java
│ │ │ ├── HttpCharSet.java
│ │ │ ├── HttpID.java
│ │ │ ├── HttpMaxRedirect.java
│ │ │ ├── HttpMaxRetry.java
│ │ │ ├── HttpMethod.java
│ │ │ ├── HttpTag.java
│ │ │ └── HttpUri.java
│ │ │ ├── data
│ │ │ ├── Charsets.java
│ │ │ ├── Consts.java
│ │ │ ├── FastJson.java
│ │ │ ├── GsonImpl.java
│ │ │ ├── HttpStatus.java
│ │ │ ├── Json.java
│ │ │ ├── NameValuePair.java
│ │ │ ├── StatisticsInfo.java
│ │ │ └── TypeToken.java
│ │ │ ├── exception
│ │ │ ├── ClientException.java
│ │ │ ├── HttpClientException.java
│ │ │ ├── HttpException.java
│ │ │ ├── HttpNetException.java
│ │ │ ├── HttpServerException.java
│ │ │ ├── NetException.java
│ │ │ ├── ServerException.java
│ │ │ └── handler
│ │ │ │ └── HttpExceptionHandler.java
│ │ │ ├── impl
│ │ │ └── huc
│ │ │ │ ├── HttpUrlClient.java
│ │ │ │ └── RetryHandler.java
│ │ │ ├── listener
│ │ │ ├── GlobalHttpListener.java
│ │ │ ├── HttpListener.java
│ │ │ └── StatisticsListener.java
│ │ │ ├── log
│ │ │ └── HttpLog.java
│ │ │ ├── network
│ │ │ └── Network.java
│ │ │ ├── parser
│ │ │ ├── DataParser.java
│ │ │ ├── FileCacheableParser.java
│ │ │ ├── MemCacheableParser.java
│ │ │ └── impl
│ │ │ │ ├── BitmapParser.java
│ │ │ │ ├── BytesParser.java
│ │ │ │ ├── FileParser.java
│ │ │ │ ├── JsonParser.java
│ │ │ │ └── StringParser.java
│ │ │ ├── request
│ │ │ ├── AbstractRequest.java
│ │ │ ├── BitmapRequest.java
│ │ │ ├── BytesRequest.java
│ │ │ ├── FileRequest.java
│ │ │ ├── JsonAbsRequest.java
│ │ │ ├── JsonRequest.java
│ │ │ ├── StringRequest.java
│ │ │ ├── content
│ │ │ │ ├── ByteArrayBody.java
│ │ │ │ ├── FileBody.java
│ │ │ │ ├── HttpBody.java
│ │ │ │ ├── InputStreamBody.java
│ │ │ │ ├── JsonBody.java
│ │ │ │ ├── SerializableBody.java
│ │ │ │ ├── StringBody.java
│ │ │ │ ├── UrlEncodedFormBody.java
│ │ │ │ └── multi
│ │ │ │ │ ├── AbstractPart.java
│ │ │ │ │ ├── BoundaryCreater.java
│ │ │ │ │ ├── BytesPart.java
│ │ │ │ │ ├── FilePart.java
│ │ │ │ │ ├── InputStreamPart.java
│ │ │ │ │ ├── MultipartBody.java
│ │ │ │ │ └── StringPart.java
│ │ │ ├── param
│ │ │ │ ├── CacheMode.java
│ │ │ │ ├── HttpCustomParam.java
│ │ │ │ ├── HttpMethods.java
│ │ │ │ ├── HttpParam.java
│ │ │ │ ├── HttpParamModel.java
│ │ │ │ ├── HttpReplace.java
│ │ │ │ ├── HttpRichParamModel.java
│ │ │ │ └── NonHttpParam.java
│ │ │ └── query
│ │ │ │ ├── JsonQueryBuilder.java
│ │ │ │ ├── ModelQueryBuilder.java
│ │ │ │ └── SimpleQueryBuilder.java
│ │ │ ├── response
│ │ │ ├── InternalResponse.java
│ │ │ └── Response.java
│ │ │ └── utils
│ │ │ ├── HexUtil.java
│ │ │ ├── HttpUtil.java
│ │ │ ├── MD5Util.java
│ │ │ ├── StringCodingUtils.java
│ │ │ └── UriUtil.java
│ └── res
│ │ └── values
│ │ └── strings.xml
│ └── test
│ └── java
│ └── com
│ └── litesuits
│ └── http
│ └── ExampleUnitTest.java
├── settings.gradle
└── web-server-sample
├── lib
├── javax.annotation.jar
├── javax.ejb.jar
├── javax.jms.jar
├── javax.persistence.jar
├── javax.resource.jar
├── javax.servlet.jar
├── javax.servlet.jsp.jar
├── javax.servlet.jsp.jstl.jar
└── javax.transaction.jar
├── src
└── com
│ └── litesuits
│ └── server
│ └── PostReceiver.java
└── web
├── WEB-INF
├── lib
│ ├── commons-codec-1.9.jar
│ ├── commons-fileupload-1.3.1.jar
│ ├── commons-io-2.4.jar
│ ├── commons-logging-1.2.jar
│ ├── fluent-hc-4.4.1.jar
│ ├── httpclient-4.4.1.jar
│ ├── httpclient-cache-4.4.1.jar
│ ├── httpclient-win-4.4.1.jar
│ ├── httpcore-4.4.1.jar
│ ├── httpmime-4.4.1.jar
│ ├── jna-4.1.0.jar
│ └── jna-platform-4.1.0.jar
└── web.xml
└── index.jsp
/.gitignore:
--------------------------------------------------------------------------------
1 | # root files
2 |
3 | # built application files
4 | *.apk
5 | *.ap_
6 | .gradle
7 |
8 | # files for the dex VM
9 | *.dex
10 |
11 | # Java class files
12 | *.class
13 |
14 | # generated files
15 | bin/
16 | gen/
17 | out/
18 | build/
19 |
20 | # Local configuration file (sdk path, etc)
21 | *.properties
22 | proguard-project.txt
23 |
24 | # Eclipse project files
25 | .classpath
26 | .project
27 | .settings
28 |
29 | # Proguard folder generated by Eclipse
30 | proguard/
31 |
32 | # Intellij project files
33 | *.iml
34 | *.ipr
35 | *.iws
36 | .idea/
37 |
38 | .gradle
39 |
40 | .DS_Store
41 |
--------------------------------------------------------------------------------
/CHANGE-LOG.md:
--------------------------------------------------------------------------------
1 | Change Log
2 |
3 | 1.0 Features
4 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5 | * 1. 单线程:基于当前线程高效率运作。
6 | * 2. 轻量级:微小的内存开销与Jar包体积,仅约 86K 。
7 | * 3. 全支持:GET, POST, PUT, DELETE, HEAD, TRACE, OPTIONS, PATCH.
8 | * 4. 全自动:一行代码将请求Java Model 转化为 Http Parameter,结果Json String 转化为 Java Model 。
9 | * 5. 易拓展:自定义 DataParser,将网络数据流自由转化为你想要的任意数据类型。
10 | * 6. 基于接口:架构灵活,轻松替换网络连接方式的核心实现方式,以及 Json 序列化库。
11 | * 7. 文件上传:支持单个、多个大文件上传。
12 | * 8. 文件下载:支持文件、Bimtap下载及其进度通知。
13 | * 9. 网络禁用:快速禁用一种、多种网络环境,比如禁用 2G,3G 。
14 | * 10. 数据统计:链接、读取时长统计,以及流量统计。
15 | * 11. 异常体系:统一的异常处理体系,简明清晰地抛出可再细分的三大类异常:客户端、网络、服务器异常。
16 | * 12. GZIP压缩:Request, Response 自动 GZIP 压缩节省流量。
17 | * 13. 自动重试:结合探测异常类型和当前网络状况,智能执行重试策略。
18 | * 14. 自动重定向:基于 30X 状态的重试,且可设置最大次数防止过度跳转。
19 | * 15. 自带简单异步执行器,方便开发者实现异步请求方案。
20 |
21 |
22 | 2.0 Features
23 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
24 | * 1. 可配置:更多更灵活的配置选择项,多达 23+ 项。
25 | * 2. 多态化:更加直观的API,输入和输出更加明确。
26 | * 3. 强并发:智能高效的并发调度,有效控制核心并发与队列控制策略。
27 | * 4. 注解化:信息配置约定更多样,如果你喜欢,可以注解 API、Method、ID、TAG、CacheMode 等参数。
28 | * 5. 多层缓存:内存命中更高效!支持多样的缓存模式,支持设置缓存有效期。
29 | * 6. 完善回调:自由设置回调当前或UI线程,自由开启上传、下载进度通知。
30 | * 7. 完善构建:提供 jar 包支持,后边支持 gradle 和 maven 。
31 |
32 | 2.2.0
33 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
34 | 1. 修复某些情况下参数无法拼接到URI的bug;
35 | 2. http参数类可以注解指定Key,避免成员变量出现java关键词,同时增加动态URL构建;
36 | 3. Request接受直接注解参数、内部构建参数(此特性已删除)。
37 |
38 | 2.3.0
39 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
40 | 1. 注解参数动态化;
41 | 2. 优化HttpRichParamModel的使用。
42 |
43 | 3.0.0
44 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
45 | 1. 添加HttpUrlConnection支持,并设置为默认HTTP客户端引擎。
46 | 2. 将Apache HTTP Client移到独立项目。
47 | 3. 优化HttpConfig的体验。
48 |
49 | 3.1.0
50 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
51 | 1. 添加通过 dir 和 key 删除缓存的方法
52 |
53 | 3.1.1
54 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
55 | 1. 修改 Request基类的 属性参数 和 extra map 参数的覆盖顺序。
56 |
57 | 3.1.3.6
58 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
59 | 1. 注意要引入 lite-go 类库
60 | 2. 解决request参数的Encode问题,解决在默写编译器下的Map遍历时泛型丢失引起的强转String问题
61 |
--------------------------------------------------------------------------------
/apache-client/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/apache-client/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 22
5 | buildToolsVersion "23.0.2"
6 |
7 | defaultConfig {
8 | minSdkVersion 9
9 | targetSdkVersion 22
10 | versionCode 1
11 | versionName "1.0"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | }
20 |
21 | dependencies {
22 | compile fileTree(dir: 'libs', include: ['*.jar'])
23 | testCompile 'junit:junit:4.12'
24 | provided project(':litehttp')
25 | }
26 |
--------------------------------------------------------------------------------
/apache-client/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/matianyu/develop/android/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/apache-client/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apache-client/src/main/java/com/litesuits/http/impl/apache/EntityBuilder.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.impl.apache;
2 |
3 | import com.litesuits.http.data.Consts;
4 | import com.litesuits.http.exception.HttpClientException;
5 | import com.litesuits.http.impl.apache.entity.FileEntity;
6 | import com.litesuits.http.impl.apache.entity.InputStreamEntity;
7 | import com.litesuits.http.impl.apache.entity.MultipartEntity;
8 | import com.litesuits.http.request.AbstractRequest;
9 | import com.litesuits.http.request.content.*;
10 | import com.litesuits.http.request.content.multi.MultipartBody;
11 | import org.apache.http.HttpEntity;
12 | import org.apache.http.entity.ByteArrayEntity;
13 | import org.apache.http.entity.StringEntity;
14 |
15 | /**
16 | * help us to build {@link org.apache.http.HttpEntity}
17 | *
18 | * @author MaTianyu
19 | * 2014-1-18上午1:41:41
20 | */
21 | public class EntityBuilder {
22 |
23 | public static HttpEntity build(AbstractRequest req) throws HttpClientException {
24 | try {
25 | HttpBody body = req.getHttpBody();
26 | if (body != null) {
27 | req.addHeader(Consts.CONTENT_TYPE, body.getContentType());
28 | if (body instanceof StringBody) {
29 | // StringBody JsonBody UrlEncodedFormBody
30 | StringBody b = (StringBody) body;
31 | return new StringEntity(b.getString(), b.getCharset());
32 | } else if (body instanceof ByteArrayBody) {
33 | // ByteArrayBody SerializableBody
34 | ByteArrayBody b = (ByteArrayBody) body;
35 | return new ByteArrayEntity(b.getBytes());
36 | } else if (body instanceof InputStreamBody) {
37 | InputStreamBody b = (InputStreamBody) body;
38 | return new InputStreamEntity(b.getInstream(), b.getInstream().available(), req);
39 | } else if (body instanceof FileBody) {
40 | FileBody b = (FileBody) body;
41 | return new FileEntity(b.getFile(), b.getContentType(), req);
42 | } else if (body instanceof MultipartBody) {
43 | return new MultipartEntity((MultipartBody) body);
44 | } else {
45 | throw new RuntimeException("Unpredictable Entity Body(非法实体)");
46 | }
47 | }
48 | } catch (Exception e) {
49 | throw new HttpClientException(e);
50 | }
51 | return null;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/apache-client/src/main/java/com/litesuits/http/impl/apache/GZIPEntityWrapper.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.impl.apache;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import java.util.zip.GZIPInputStream;
6 |
7 | import org.apache.http.HttpEntity;
8 | import org.apache.http.entity.HttpEntityWrapper;
9 |
10 | /**
11 | * Enclosing inputstream for gzip decoded data.
12 | * Improve network transmission speed quite a lot.
13 | *
14 | * @author MaTianyu
15 | * 2014-1-1下午7:39:45
16 | */
17 | class GZIPEntityWrapper extends HttpEntityWrapper {
18 | public GZIPEntityWrapper(HttpEntity wrapped) {
19 | super(wrapped);
20 | }
21 |
22 | @Override
23 | public InputStream getContent() throws IOException {
24 | return new GZIPInputStream(wrappedEntity.getContent());
25 | }
26 |
27 | @Override
28 | public long getContentLength() {
29 | //unknown
30 | return -1;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/apache-client/src/main/java/com/litesuits/http/impl/apache/HttpPatch.java:
--------------------------------------------------------------------------------
1 | /*
2 | * ====================================================================
3 | * Licensed to the Apache Software Foundation (ASF) under one
4 | * or more contributor license agreements. See the NOTICE file
5 | * distributed with this work for additional information
6 | * regarding copyright ownership. The ASF licenses this file
7 | * to you under the Apache License, Version 2.0 (the
8 | * "License"); you may not use this file except in compliance
9 | * with the License. You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing,
14 | * software distributed under the License is distributed on an
15 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | * KIND, either express or implied. See the License for the
17 | * specific language governing permissions and limitations
18 | * under the License.
19 | * ====================================================================
20 | *
21 | * This software consists of voluntary contributions made by many
22 | * individuals on behalf of the Apache Software Foundation. For more
23 | * information on the Apache Software Foundation, please see
24 | * .
25 | *
26 | */
27 |
28 | package com.litesuits.http.impl.apache;
29 |
30 | import java.net.URI;
31 |
32 | import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
33 |
34 | /**
35 | * HTTP PATCH method.
36 | *
37 | * The HTTP PATCH method is defined in RF5789:
The PATCH
39 | * method requests that a set of changes described in the request entity be
40 | * applied to the resource identified by the Request- URI. Differs from the PUT
41 | * method in the way the server processes the enclosed entity to modify the
42 | * resource identified by the Request-URI. In a PUT request, the enclosed entity
43 | * origin server, and the client is requesting that the stored version be
44 | * replaced. With PATCH, however, the enclosed entity contains a set of
45 | * instructions describing how a resource currently residing on the origin
46 | * server should be modified to produce a new version.
47 | *
48 | *
49 | * @since 4.2
50 | */
51 | @NotThreadSafe
52 | public class HttpPatch extends HttpEntityEnclosingRequestBase {
53 |
54 | public final static String METHOD_NAME = "PATCH";
55 |
56 | public HttpPatch() {
57 | super();
58 | }
59 |
60 | public HttpPatch(final URI uri) {
61 | super();
62 | setURI(uri);
63 | }
64 |
65 | public HttpPatch(final String uri) {
66 | super();
67 | setURI(URI.create(uri));
68 | }
69 |
70 | @Override
71 | public String getMethod() {
72 | return METHOD_NAME;
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/apache-client/src/main/java/com/litesuits/http/impl/apache/MyLayeredSocketFactory.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.impl.apache;
2 |
3 | import java.io.IOException;
4 | import java.lang.reflect.Field;
5 | import java.net.InetAddress;
6 | import java.net.Socket;
7 |
8 | import javax.net.SocketFactory;
9 |
10 | import org.apache.http.conn.scheme.LayeredSocketFactory;
11 | import org.apache.http.conn.ssl.SSLSocketFactory;
12 | import org.apache.http.params.HttpParams;
13 |
14 |
15 | /**
16 | * Android had a bug where HTTPS made reverse DNS lookups (fixed in Ice Cream Sandwich)
17 | * http://code.google.com/p/android/issues/detail?id=13117
18 | *
19 | * @author MaTianyu
20 | * 2014-1-10上午12:17:04
21 | */
22 | public class MyLayeredSocketFactory implements LayeredSocketFactory {
23 | SSLSocketFactory delegate = SSLSocketFactory.getSocketFactory();
24 |
25 | @Override
26 | public Socket createSocket() throws IOException {
27 | return delegate.createSocket();
28 | }
29 |
30 | @Override
31 | public Socket connectSocket(Socket sock, String host, int port, InetAddress localAddress, int localPort, HttpParams params)
32 | throws IOException {
33 | return delegate.connectSocket(sock, host, port, localAddress, localPort, params);
34 | }
35 |
36 | @Override
37 | public boolean isSecure(Socket sock) throws IllegalArgumentException {
38 | return delegate.isSecure(sock);
39 | }
40 |
41 | @Override
42 | public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException {
43 | injectHostname(socket, host);
44 | return delegate.createSocket(socket, host, port, autoClose);
45 | }
46 |
47 | private void injectHostname(Socket socket, String host) {
48 | try {
49 | Field field = InetAddress.class.getDeclaredField("hostName");
50 | field.setAccessible(true);
51 | field.set(socket.getInetAddress(), host);
52 | } catch (Exception ignored) {
53 | }
54 | }
55 | };
--------------------------------------------------------------------------------
/apache-client/src/main/java/com/litesuits/http/impl/apache/MySSLSocketFactory.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.impl.apache;
2 |
3 | import org.apache.http.conn.ssl.SSLSocketFactory;
4 |
5 | import javax.net.ssl.SSLContext;
6 | import javax.net.ssl.TrustManager;
7 | import javax.net.ssl.X509TrustManager;
8 | import java.io.IOException;
9 | import java.net.Socket;
10 | import java.security.*;
11 |
12 | /**
13 | * This file is introduced to fix HTTPS Post bug on API < ICS see
14 | * http://code.google.com/p/android/issues/detail?id=13117#c14
Warning! This omits SSL
15 | * certificate validation on every device, use with caution
16 | */
17 | public class MySSLSocketFactory extends SSLSocketFactory {
18 | SSLContext sslContext = SSLContext.getInstance("TLS");
19 |
20 | public MySSLSocketFactory(KeyStore truststore)
21 | throws NoSuchAlgorithmException, KeyManagementException,
22 | KeyStoreException, UnrecoverableKeyException {
23 | super(truststore);
24 |
25 | TrustManager tm = new X509TrustManager() {
26 | public java.security.cert.X509Certificate[] getAcceptedIssuers() {
27 | return null;
28 | }
29 |
30 | @Override
31 | public void checkClientTrusted(
32 | java.security.cert.X509Certificate[] chain, String authType)
33 | throws java.security.cert.CertificateException {
34 | }
35 |
36 | @Override
37 | public void checkServerTrusted(
38 | java.security.cert.X509Certificate[] chain, String authType)
39 | throws java.security.cert.CertificateException {
40 | }
41 | };
42 | sslContext.init(null, new TrustManager[]{tm}, null);
43 | }
44 |
45 | @Override
46 | public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException {
47 | return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
48 | }
49 |
50 | @Override
51 | public Socket createSocket() throws IOException {
52 | return sslContext.getSocketFactory().createSocket();
53 | }
54 |
55 | public static KeyStore getKeystore() {
56 | KeyStore trustStore = null;
57 | try {
58 | trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
59 | trustStore.load(null, null);
60 | } catch (Throwable t) {
61 | t.printStackTrace();
62 | }
63 | return trustStore;
64 | }
65 |
66 | public static SSLSocketFactory getFixedSocketFactory() {
67 | SSLSocketFactory socketFactory;
68 | try {
69 | socketFactory = new MySSLSocketFactory(getKeystore());
70 | socketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
71 | } catch (Throwable t) {
72 | t.printStackTrace();
73 | socketFactory = SSLSocketFactory.getSocketFactory();
74 | }
75 | return socketFactory;
76 | }
77 |
78 | }
--------------------------------------------------------------------------------
/apache-client/src/main/java/com/litesuits/http/impl/apache/NotThreadSafe.java:
--------------------------------------------------------------------------------
1 | /*
2 | * ====================================================================
3 | * Licensed to the Apache Software Foundation (ASF) under one
4 | * or more contributor license agreements. See the NOTICE file
5 | * distributed with this work for additional information
6 | * regarding copyright ownership. The ASF licenses this file
7 | * to you under the Apache License, Version 2.0 (the
8 | * "License"); you may not use this file except in compliance
9 | * with the License. You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing,
14 | * software distributed under the License is distributed on an
15 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | * KIND, either express or implied. See the License for the
17 | * specific language governing permissions and limitations
18 | * under the License.
19 | * ====================================================================
20 | *
21 | * This software consists of voluntary contributions made by many
22 | * individuals on behalf of the Apache Software Foundation. For more
23 | * information on the Apache Software Foundation, please see
24 | * .
25 | *
26 | */
27 | package com.litesuits.http.impl.apache;
28 |
29 | import java.lang.annotation.Documented;
30 | import java.lang.annotation.ElementType;
31 | import java.lang.annotation.Retention;
32 | import java.lang.annotation.RetentionPolicy;
33 | import java.lang.annotation.Target;
34 |
35 | /**
36 | * The class to which this annotation is applied is not thread-safe.
37 | * This annotation primarily exists for clarifying the non-thread-safety of a class
38 | * that might otherwise be assumed to be thread-safe, despite the fact that it is a bad
39 | * idea to assume a class is thread-safe without good reason.
40 | *
41 | * @see ThreadSafe
42 | *
43 | * Based on code developed by Brian Goetz and Tim Peierls and concepts
44 | * published in 'Java Concurrency in Practice' by Brian Goetz, Tim Peierls,
45 | * Joshua Bloch, Joseph Bowbeer, David Holmes and Doug Lea.
46 | */
47 | @Documented
48 | @Target(ElementType.TYPE)
49 | @Retention(RetentionPolicy.CLASS) // The original version used RUNTIME
50 | public @interface NotThreadSafe {
51 | }
52 |
--------------------------------------------------------------------------------
/apache-client/src/main/java/com/litesuits/http/impl/apache/StandardHttpRequestRetryHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * ====================================================================
3 | * Licensed to the Apache Software Foundation (ASF) under one
4 | * or more contributor license agreements. See the NOTICE file
5 | * distributed with this work for additional information
6 | * regarding copyright ownership. The ASF licenses this file
7 | * to you under the Apache License, Version 2.0 (the
8 | * "License"); you may not use this file except in compliance
9 | * with the License. You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing,
14 | * software distributed under the License is distributed on an
15 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | * KIND, either express or implied. See the License for the
17 | * specific language governing permissions and limitations
18 | * under the License.
19 | * ====================================================================
20 | *
21 | * This software consists of voluntary contributions made by many
22 | * individuals on behalf of the Apache Software Foundation. For more
23 | * information on the Apache Software Foundation, please see
24 | * .
25 | *
26 | */
27 |
28 | package com.litesuits.http.impl.apache;
29 |
30 | import org.apache.http.HttpRequest;
31 |
32 | import java.util.Locale;
33 | import java.util.Map;
34 | import java.util.concurrent.ConcurrentHashMap;
35 |
36 | /**
37 | * {@link org.apache.http.client.HttpRequestRetryHandler} which assumes
38 | * that all requested HTTP methods which should be idempotent according
39 | * to RFC-2616 are in fact idempotent and can be retried.
40 | *
41 | * According to RFC-2616 section 9.1.2 the idempotent HTTP methods are:
42 | * GET, HEAD, PUT, DELETE, OPTIONS, and TRACE
43 | *
44 | * @since 4.2
45 | */
46 | public class StandardHttpRequestRetryHandler extends DefaultHttpRequestRetryHandler {
47 |
48 | private final Map idempotentMethods;
49 |
50 | /**
51 | * Default constructor
52 | */
53 | public StandardHttpRequestRetryHandler(final int retryCount, final boolean requestSentRetryEnabled) {
54 | super(retryCount, requestSentRetryEnabled);
55 | this.idempotentMethods = new ConcurrentHashMap();
56 | this.idempotentMethods.put("GET", Boolean.TRUE);
57 | this.idempotentMethods.put("HEAD", Boolean.TRUE);
58 | this.idempotentMethods.put("PUT", Boolean.TRUE);
59 | this.idempotentMethods.put("DELETE", Boolean.TRUE);
60 | this.idempotentMethods.put("OPTIONS", Boolean.TRUE);
61 | this.idempotentMethods.put("TRACE", Boolean.TRUE);
62 | }
63 |
64 | /**
65 | * Default constructor
66 | */
67 | public StandardHttpRequestRetryHandler() {
68 | this(3, false);
69 | }
70 |
71 | @Override
72 | protected boolean handleAsIdempotent(final HttpRequest request) {
73 | if (request == null) {
74 | return true;
75 | }
76 | final String method = request.getRequestLine().getMethod().toUpperCase(Locale.US);
77 | final Boolean b = this.idempotentMethods.get(method);
78 | return b != null && b.booleanValue();
79 | }
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/apache-client/src/main/java/com/litesuits/http/impl/apache/TrustSSLSocketFactory.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.impl.apache;
2 |
3 | import java.io.IOException;
4 | import java.net.Socket;
5 | import java.security.KeyManagementException;
6 | import java.security.KeyStore;
7 | import java.security.KeyStoreException;
8 | import java.security.NoSuchAlgorithmException;
9 | import java.security.UnrecoverableKeyException;
10 |
11 | import javax.net.ssl.SSLContext;
12 | import javax.net.ssl.TrustManager;
13 | import javax.net.ssl.X509TrustManager;
14 |
15 | import org.apache.http.conn.ssl.SSLSocketFactory;
16 |
17 | /**
18 | * fixed https request bug
19 | *
20 | * @author MaTianyu
21 | * 2014-1-1下午5:09:33
22 | */
23 | class TrustSSLSocketFactory extends SSLSocketFactory {
24 | SSLContext sslContext = SSLContext.getInstance("TLS");
25 |
26 | private TrustSSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException,
27 | UnrecoverableKeyException {
28 | super(truststore);
29 | TrustManager tm = new X509TrustManager() {
30 | public java.security.cert.X509Certificate[] getAcceptedIssuers() {
31 | return null;
32 | }
33 |
34 | @Override
35 | public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType)
36 | throws java.security.cert.CertificateException {
37 | }
38 |
39 | @Override
40 | public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType)
41 | throws java.security.cert.CertificateException {
42 | }
43 | };
44 | sslContext.init(null, new TrustManager[]{tm}, null);
45 | }
46 |
47 | @Override
48 | public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException {
49 | return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
50 | }
51 |
52 | @Override
53 | public Socket createSocket() throws IOException {
54 | return sslContext.getSocketFactory().createSocket();
55 | }
56 |
57 | public static SSLSocketFactory getSocketFactory() {
58 | SSLSocketFactory socketFactory;
59 | try {
60 | KeyStore trustStore = getKeyStore();
61 | socketFactory = new TrustSSLSocketFactory(trustStore);
62 | socketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
63 | } catch (Throwable t) {
64 | t.printStackTrace();
65 | socketFactory = SSLSocketFactory.getSocketFactory();
66 | }
67 | return socketFactory;
68 | }
69 |
70 | public static KeyStore getKeyStore() {
71 | KeyStore trustStore = null;
72 | try {
73 | trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
74 | trustStore.load(null, null);
75 | } catch (Throwable t) {
76 | t.printStackTrace();
77 | }
78 | return trustStore;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/apache-client/src/main/java/com/litesuits/http/impl/apache/entity/FileEntity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * ====================================================================
3 | * Licensed to the Apache Software Foundation (ASF) under one
4 | * or more contributor license agreements. See the NOTICE file
5 | * distributed with this work for additional information
6 | * regarding copyright ownership. The ASF licenses this file
7 | * to you under the Apache License, Version 2.0 (the
8 | * "License"); you may not use this file except in compliance
9 | * with the License. You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing,
14 | * software distributed under the License is distributed on an
15 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | * KIND, either express or implied. See the License for the
17 | * specific language governing permissions and limitations
18 | * under the License.
19 | * ====================================================================
20 | *
21 | * This software consists of voluntary contributions made by many
22 | * individuals on behalf of the Apache Software Foundation. For more
23 | * information on the Apache Software Foundation, please see
24 | * .
25 | *
26 | */
27 |
28 | package com.litesuits.http.impl.apache.entity;
29 |
30 | import com.litesuits.http.request.AbstractRequest;
31 |
32 | import java.io.*;
33 |
34 | /**
35 | * A self contained, repeatable entity that obtains its content from a file.
36 | *
37 | * @since 4.0
38 | */
39 | public class FileEntity extends AbstractHttpEntity implements Cloneable {
40 |
41 | protected final File file;
42 |
43 | public FileEntity(final File file, final String contentType, AbstractRequest request) {
44 | super();
45 | if (file == null) {
46 | throw new IllegalArgumentException("File may not be null");
47 | }
48 | this.file = file;
49 | setContentType(contentType);
50 | setRequest(request);
51 | }
52 |
53 | public boolean isRepeatable() {
54 | return true;
55 | }
56 |
57 | public long getContentLength() {
58 | return this.file.length();
59 | }
60 |
61 | public InputStream getContent() throws IOException {
62 | return new FileInputStream(this.file);
63 | }
64 |
65 | /**
66 | * modified by MaTianyu
67 | */
68 | public void writeTo(final OutputStream outstream) throws IOException {
69 | if (outstream == null) {
70 | throw new IllegalArgumentException("Output stream may not be null");
71 | }
72 | bytesWritten = 0;
73 | totalSize = file.length();
74 | InputStream instream = new FileInputStream(this.file);
75 | try {
76 | byte[] tmp = new byte[BUFFER_SIZE];
77 | int l;
78 | while ((l = instream.read(tmp)) != -1) {
79 | outstream.write(tmp, 0, l);
80 | updateProgress(l);
81 | }
82 | outstream.flush();
83 | } finally {
84 | instream.close();
85 | }
86 | }
87 |
88 | /**
89 | * Tells that this entity is not streaming.
90 | *
91 | * @return false
92 | */
93 | public boolean isStreaming() {
94 | return false;
95 | }
96 |
97 | } // class FileEntity
98 |
--------------------------------------------------------------------------------
/apache-client/src/main/java/com/litesuits/http/impl/apache/entity/InputStreamEntity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * ====================================================================
3 | * Licensed to the Apache Software Foundation (ASF) under one
4 | * or more contributor license agreements. See the NOTICE file
5 | * distributed with this work for additional information
6 | * regarding copyright ownership. The ASF licenses this file
7 | * to you under the Apache License, Version 2.0 (the
8 | * "License"); you may not use this file except in compliance
9 | * with the License. You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing,
14 | * software distributed under the License is distributed on an
15 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | * KIND, either express or implied. See the License for the
17 | * specific language governing permissions and limitations
18 | * under the License.
19 | * ====================================================================
20 | *
21 | * This software consists of voluntary contributions made by many
22 | * individuals on behalf of the Apache Software Foundation. For more
23 | * information on the Apache Software Foundation, please see
24 | * .
25 | *
26 | */
27 |
28 | package com.litesuits.http.impl.apache.entity;
29 |
30 | import com.litesuits.http.request.AbstractRequest;
31 |
32 | import java.io.IOException;
33 | import java.io.InputStream;
34 | import java.io.OutputStream;
35 |
36 | /**
37 | * A streamed, non-repeatable entity that obtains its content from
38 | * an {@link InputStream}.
39 | *
40 | * @since 4.0
41 | */
42 | public class InputStreamEntity extends AbstractHttpEntity {
43 |
44 | private final InputStream content;
45 | private final long length;
46 | private boolean consumed = false;
47 |
48 | public InputStreamEntity(final InputStream instream, long length, AbstractRequest request) {
49 | super();
50 | if (instream == null) {
51 | throw new IllegalArgumentException("Source input stream may not be null");
52 | }
53 | this.content = instream;
54 | this.length = length;
55 | setRequest(request);
56 | }
57 |
58 | public boolean isRepeatable() {
59 | return false;
60 | }
61 |
62 | public long getContentLength() {
63 | return this.length;
64 | }
65 |
66 | public InputStream getContent() throws IOException {
67 | return this.content;
68 | }
69 |
70 | /**
71 | * modified by MaTianyu
72 | */
73 | public void writeTo(final OutputStream outstream) throws IOException {
74 | if (outstream == null) {
75 | throw new IllegalArgumentException("Output stream may not be null");
76 | }
77 | InputStream instream = this.content;
78 | byte[] buffer = new byte[BUFFER_SIZE];
79 | int l;
80 | bytesWritten = 0;
81 | if (this.length < 0) {
82 | totalSize = instream.available();
83 | // consume until EOF
84 | while ((l = instream.read(buffer)) != -1) {
85 | outstream.write(buffer, 0, l);
86 | updateProgress(l);
87 | }
88 | } else {
89 | // consume no more than length
90 | totalSize = this.length;
91 | long remaining = this.length;
92 | while (remaining > 0) {
93 | l = instream.read(buffer, 0, (int) Math.min(BUFFER_SIZE, remaining));
94 | if (l == -1) {
95 | break;
96 | }
97 | outstream.write(buffer, 0, l);
98 | updateProgress(l);
99 | remaining -= l;
100 | }
101 | }
102 | this.consumed = true;
103 | }
104 |
105 | // non-javadoc, see interface HttpEntity
106 | public boolean isStreaming() {
107 | return !this.consumed;
108 | }
109 |
110 | // non-javadoc, see interface HttpEntity
111 | public void consumeContent() throws IOException {
112 | this.consumed = true;
113 | // If the input stream is from a connection, closing it will read to
114 | // the end of the content. Otherwise, we don't care what it does.
115 | this.content.close();
116 | }
117 |
118 | } // class InputStreamEntity
119 |
--------------------------------------------------------------------------------
/apache-client/src/main/java/com/litesuits/http/impl/apache/entity/MultipartEntity.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.impl.apache.entity;
2 |
3 | import com.litesuits.http.request.content.multi.MultipartBody;
4 | import org.apache.http.Header;
5 | import org.apache.http.HttpEntity;
6 | import org.apache.http.message.BasicHeader;
7 |
8 | import java.io.IOException;
9 | import java.io.InputStream;
10 | import java.io.OutputStream;
11 |
12 |
13 | /**
14 | * Simplified multipart entity mainly used for sending one or more files.
15 | *
16 | * @author MaTianyu
17 | */
18 | public class MultipartEntity implements HttpEntity {
19 |
20 | private boolean isRepeatable = false;
21 | private MultipartBody multipartBody;
22 |
23 | public MultipartEntity(MultipartBody multipartBody) {
24 | this.multipartBody = multipartBody;
25 | }
26 |
27 | @Override
28 | public long getContentLength() {
29 | return multipartBody.getContentLength();
30 | }
31 |
32 | @Override
33 | public Header getContentType() {
34 | return new BasicHeader("Content-Type", multipartBody.getContentType());
35 | }
36 |
37 | @Override
38 | public void writeTo(final OutputStream outstream) throws IOException {
39 | multipartBody.writeTo(outstream);
40 | }
41 |
42 | @Override
43 | public boolean isChunked() {
44 | return false;
45 | }
46 |
47 | public void setIsRepeatable(boolean isRepeatable) {
48 | this.isRepeatable = isRepeatable;
49 | }
50 |
51 | @Override
52 | public boolean isRepeatable() {
53 | return isRepeatable;
54 | }
55 |
56 | @Override
57 | public boolean isStreaming() {
58 | return false;
59 | }
60 |
61 | @Override
62 | public Header getContentEncoding() {
63 | return null;
64 | }
65 |
66 | @Override
67 | public void consumeContent() throws IOException, UnsupportedOperationException {
68 | if (isStreaming()) {
69 | throw new UnsupportedOperationException("Streaming entity does not implement #consumeContent()");
70 | }
71 | }
72 |
73 | @Override
74 | public InputStream getContent() throws IOException, UnsupportedOperationException {
75 | throw new UnsupportedOperationException("getContent() is not supported. Use writeTo() instead.");
76 | }
77 |
78 | }
--------------------------------------------------------------------------------
/apache-client/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | litehttp-v3-apache-client
3 |
4 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.1.0'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | }
19 | }
20 |
21 | task clean(type: Delete) {
22 | delete rootProject.buildDir
23 | }
24 |
--------------------------------------------------------------------------------
/docs/1-first-use.md:
--------------------------------------------------------------------------------
1 | # Android网络通信框架 LiteHttp2.0 实用教程
2 |
3 | 标签(空格分隔): litehttp教程 android网络通信教程 android http http最佳实践
4 |
5 | ---
6 |
7 | 本系列文章面向各级别尤其中高级android开发者,将展示开源网络通信框架LiteHttp的核心用法,讲解其关键功能的运作原理。
8 | 希望可以让开发者既能熟练使用、修改开源HTTP框架高效完成日常开发任务,又能深入理解litehttp类库本身以及android网络通信相关知识。同时传达了一些框架作者在日常开发中的一些最佳实践,仅作抛砖引玉。
9 |
10 | ##第一节:初步使用
11 |
12 | ###初始化及单例
13 |
14 | 初始化LiteHttp需要传入一个HttpConfig的实例来配置各项参数,不传入即表示使用全部使用默认设置。
15 |
16 | 需要注意的是,一个App仅需要构建一个LiteHttp的实例即可,即单例模式,这样才能最节省系统资源,多个实例并不提升效率。
17 |
18 | 使用默认配置:
19 | ```java
20 | LiteHttp liteHttp = LiteHttp.newApacheHttpClient(null);
21 | ```
22 |
23 | 简单自定义配置:
24 | ```java
25 | HttpConfig config = new HttpConfig(activity);
26 |
27 | // set app context
28 | config.setContext(activity);
29 |
30 | // custom User-Agent
31 | config.setUserAgent("Mozilla/5.0 (...)");
32 |
33 | // connect timeout: 10s, socket timeout: 10s
34 | config.setTimeOut(10000, 10000);
35 |
36 | // new with config
37 | LiteHttp liteHttp = LiteHttp.newApacheHttpClient(config);
38 | ```
39 |
40 | 这个案例示范了context(用于网络状态判断,获取网络类型),User-Agent,连接、读取超时参数配置。
41 | 更多的配置项有达23+项之多,非常的灵活,后边会有专门章节详细说明。
42 |
43 | ###发起请求
44 |
45 | 我们定义一个合法的http地址,如
46 | ```java
47 | String url = "http://baidu.com";
48 | ```
49 |
50 | 发起异步请求:
51 | ```java
52 | liteHttp.executeAsync(new StringRequest(url));
53 | ```
54 |
55 | 异步获取原始byte:
56 | ```java
57 | liteHttp.executeAsync(new BytesRequest(url));
58 | ```
59 |
60 | 异步加载一张位图:
61 | ```java
62 | String saveToPath = "/sdcard/a.png";
63 | liteHttp.executeAsync(new BitmapRequest(url,saveToPath));
64 | ```
65 | saveToPath用来输入一个你指定的文件位置,位图将会保存到这里,不传入路径则分两种情况:
66 | - 缓存未启用:仅载入内存,不做文件存储。
67 | - 缓存开启:保存默认位置,默认存储位置和下面[下载文件]的规则一致。
68 |
69 | 异步下载一个文件:
70 | ```java
71 | liteHttp.executeAsync(new FileRequest(url,saveToPath));
72 | ```
73 | saveToPath用来输入一个你指定的文件位置,文件将会保存到这里,传入 null 则保存缓存默认位置。
74 |
75 | 默认位置规则:
76 | - 如果为请求设置了 Cache-Key,则取其为文件名字
77 | - 反之根据 Url 生成文件名字
78 | 文件夹位置在HttpConfig设置。
79 |
80 | 我们知道了怎么发起异步请求,那么请求是成功还是失败,成功如何获取结果,失败如何获取异常?
81 |
82 | ###处理结果
83 | 获取 String 的请求:
84 | ```java
85 | liteHttp.executeAsync(new StringRequest(url).setHttpListener(new HttpListener() {
86 | @Override
87 | public void onSuccess(String s, Response response) {
88 | // 成功:主线程回调,反馈一个string
89 | }
90 |
91 | @Override
92 | public void onFailure(HttpException e, Response response) {
93 | // 失败:主线程回调,反馈异常
94 | }
95 | }));
96 | ```
97 | 下载 File 的请求:
98 | ```java
99 | liteHttp.executeAsync(new FileRequest(url,saveToPath).setHttpListener(
100 | new HttpListener(true, true, true) {
101 |
102 | @Override
103 | public void onSuccess(File file, Response response) {
104 | }
105 |
106 | @Override
107 | public void onFailure(HttpException e, Response response) {
108 | }
109 |
110 | @Override
111 | public void onLoading(AbstractRequest request, long total, long len) {
112 | // 进度通知
113 | }
114 | })
115 | );
116 | ```
117 | 其他模式的请求,用法一样,这里不再多举。
118 |
119 | 值得注意的是 HttpListener 有多个参数可以设置:
120 | HttpListener(boolean runOnUiThread, boolean readingNotify, boolean uploadingNotify)
121 | 分别用于设置:
122 | - 开始、成功、失败、重试、上传、下载等所有回调是否在主线程(子线程回调性能更高,但不可操作UI)
123 | - 是否开启下载进度通知
124 | - 是否开启上传进度通知
125 |
126 | 注意,刚才提到,上传和下载同时是否在主线程被回调取决于第一个参数。
127 |
--------------------------------------------------------------------------------
/docs/2-async-request.md:
--------------------------------------------------------------------------------
1 | # Android网络通信框架 LiteHttp2.0 实用教程
2 |
3 | 标签(空格分隔): litehttp教程 android网络通信教程 android http http最佳实践
4 |
5 | ---
6 |
7 | 本系列文章面向各级别尤其中高级android开发者,将展示开源网络通信框架LiteHttp的核心用法,讲解其关键功能的运作原理。
8 | 希望可以让开发者既能熟练使用、修改开源HTTP框架高效完成日常开发任务,又能深入理解litehttp类库本身以及android网络通信相关知识。同时传达了一些框架作者在日常开发中的一些最佳实践,仅作抛砖引玉。
9 |
10 | ##第二节:异步与同步请求
11 |
12 | ###异步请求
13 | 异步请求有两种
14 |
15 | ```java
16 | // 1.0 init request
17 | final StringRequest request = new StringRequest(url).setHttpListener(
18 | new HttpListener() {
19 | @Override
20 | public void onSuccess(String s, Response response) {
21 | HttpUtil.showTips(activity, "LiteHttp2.0", s);
22 | response.printInfo();
23 | }
24 |
25 | @Override
26 | public void onFailure(HttpException e, Response response) {
27 | HttpUtil.showTips(activity, "LiteHttp2.0", e.toString());
28 | }
29 | }
30 | );
31 |
32 | // 1.1 execute async
33 | liteHttp.executeAsync(request);
34 |
35 | // 1.2 perform async
36 | FutureTask task = liteHttp.performAsync(request);
37 | ```
38 |
39 | 简单自定义配置:
40 | ```java
41 | HttpConfig config = new HttpConfig(activity);
42 |
43 | // set app context
44 | config.setContext(activity);
45 |
46 | // custom User-Agent
47 | config.setUserAgent("Mozilla/5.0 (...)");
48 |
49 | // connect timeout: 10s, socket timeout: 10s
50 | config.setTimeOut(10000, 10000);
51 |
52 | // new with config
53 | LiteHttp liteHttp = LiteHttp.newApacheHttpClient(config);
54 | ```
55 |
56 | 这个案例示范了context(用于网络状态判断,获取网络类型),User-Agent,连接、读取超时参数配置。
57 | 更多的配置项有达23+项之多,非常的灵活,后边会有专门章节详细说明。
58 |
59 | ###初步使用
60 |
61 | 我们定义一个合法的http地址,如
62 | ```java
63 | String url = "http://baidu.com";
64 | ```
65 |
66 | 发起异步请求:
67 | ```java
68 | liteHttp.executeAsync(new StringRequest(url));
69 | ```
70 |
71 | 异步获取原始byte:
72 | ```java
73 | liteHttp.executeAsync(new BytesRequest(url));
74 | ```
75 |
76 | 异步加载一张位图:
77 | ```java
78 | String saveToPath = "/sdcard/a.png";
79 | liteHttp.executeAsync(new BitmapRequest(url,saveToPath));
80 | ```
81 | saveToPath用来输入一个你指定的文件位置,位图将会保存到这里,不传入路径则分两种情况:
82 | - 缓存未启用:仅载入内存,不做文件存储。
83 | - 缓存开启:保存默认位置,默认存储位置和下面[下载文件]的规则一致。
84 |
85 | 异步下载一个文件:
86 | ```java
87 | liteHttp.executeAsync(new FileRequest(url,saveToPath));
88 | ```
89 | saveToPath用来输入一个你指定的文件位置,文件将会保存到这里,传入 null 则保存缓存默认位置。
90 |
91 | 默认位置规则:
92 | - 如果为请求设置了 Cache-Key,则取其为文件名字
93 | - 反之根据 Url 生成文件名字
94 | 文件夹位置在HttpConfig设置。
95 |
96 | 我们知道了怎么发起异步请求,那么请求是成功还是失败,成功如何获取结果,失败如何获取异常?
97 |
98 | ###处理结果
99 | 获取 String 的请求:
100 | ```java
101 | liteHttp.executeAsync(new StringRequest(url).setHttpListener(new HttpListener() {
102 | @Override
103 | public void onSuccess(String s, Response response) {
104 | // 成功:主线程回调,反馈一个string
105 | }
106 |
107 | @Override
108 | public void onFailure(HttpException e, Response response) {
109 | // 失败:主线程回调,反馈异常
110 | }
111 | }));
112 | ```
113 | 下载 File 的请求:
114 | ```java
115 | liteHttp.executeAsync(new FileRequest(url,saveToPath).setHttpListener(
116 | new HttpListener(true, true, true) {
117 |
118 | @Override
119 | public void onSuccess(File file, Response response) {
120 | }
121 |
122 | @Override
123 | public void onFailure(HttpException e, Response response) {
124 | }
125 |
126 | @Override
127 | public void onLoading(AbstractRequest request, long total, long len) {
128 | // 进度通知
129 | }
130 | })
131 | );
132 | ```
133 | 其他模式的请求,用法一样,这里不再多举。
134 |
135 | 值得注意的是 HttpListener 有多个参数可以设置:
136 | HttpListener(boolean runOnUiThread, boolean readingNotify, boolean uploadingNotify)
137 | 分别用于设置:
138 | - 开始、成功、失败、重试、上传、下载等所有回调是否在主线程(子线程回调性能更高,但不可操作UI)
139 | - 是否开启下载进度通知
140 | - 是否开启上传进度通知
141 |
142 | 注意,刚才提到,上传和下载同时是否在主线程被回调取决于第一个参数。
143 |
--------------------------------------------------------------------------------
/docs/lite-http-0-大纲.md:
--------------------------------------------------------------------------------
1 | # Android网络通信框架LiteHttp 开篇简介和大纲目录
2 |
3 | 标签: litehttp2.x版本系列教程
4 |
5 | ---
6 | 官网: http://litesuits.com
7 |
8 | QQ群: [大群 47357508][1] , [二群 42960650][2]
9 |
10 | [Android网络框架为什么可以选用lite-http?][3]
11 |
12 | [lite-http 初步使用 和 快速起步上手][4]
13 |
14 | 本系列文章面向android开发者,展示开源网络通信框架LiteHttp的主要用法,并讲解其关键功能的运作原理,同时传达了一些框架作者在日常开发中的一些最佳实践和经验。
15 |
16 | ---
17 | # LiteHttp之开篇简介和大纲目录
18 |
19 | ### 1. lite-http是什么? (・̆⍛・̆)
20 |
21 | > LiteHttp是一款简单、智能、灵活的HTTP框架库,它在请求和响应层面做到了全自动构建和解析,主要用于Android快速开发。
22 |
23 | ### 2. 为什么选lite-http? (•́ ₃ •̀)
24 |
25 | 简单、强大,线程无关,一行代码搞定API请求和数据转化:
26 | ```java
27 | User user = liteHttp.get(url, User.class);
28 | ```
29 |
30 | 当然也可以开启线程异步下载文件:
31 | ```java
32 | liteHttp.executeAsync(new FileRequest(url,path).setHttpListener(
33 | new HttpListener(true, true, true) {
34 |
35 | @Override
36 | public void onLoading(AbstractRequest request, long total, long len) {
37 | // 进度通知
38 | }
39 |
40 | })
41 | );
42 | ```
43 |
44 | 通过注解约定完成异步请求:
45 | ```java
46 | @HttpUri(loginUrl)
47 | class LoginParam extends HttpRichParamModel {
48 | private String name;
49 | private String password;
50 |
51 | public LoginParam(String name, String password) {
52 | this.name = name;
53 | this.password = password;
54 | }
55 | }
56 | liteHttp.executeAsync(new LoginParam("lucy", "123456"));
57 | ```
58 | 将构建类似下面请求:http://xxx?name=lucy&password=123456
59 |
60 | 案例详情可见我另一篇lite-http引言文章:[LiteHttp 引言:开发者为什么要选LiteHttp??][5]
61 |
62 | ### 3. lite-http有什么特点? (´ڡ`)
63 |
64 | - 轻量级:微小的内存开销与Jar包体积,99K左右。
65 |
66 | - 单线程:请求本身具有线程无关特性,基于当前线程高效率运作。
67 |
68 | - 全支持:GET, POST, PUT, DELETE, HEAD, TRACE, OPTIONS, PATCH。
69 |
70 | - 全自动:一行代码自动完成Model与Parameter、Json与Model。
71 |
72 | - 可配置:更多更灵活的配置选择项,多达 23+ 项。
73 |
74 | - 多态化:更加直观的API,输入和输出更加明确。
75 |
76 | - 强并发:自带强大的并发调度器,有效控制任务调度与队列控制策略。
77 |
78 | - 注解化:通过注解约定参数,URL、Method、ID、TAG等都可约定。
79 |
80 | - 易拓展:自定义DataParser将网络数据流转化为你想要的数据类型。
81 |
82 | - 可替换:基于接口,轻松替换网络连接实现方式和Json序列化库。
83 |
84 | - 多层缓存:内存命中更高效!多种缓存模式,支持设置缓存有效期。
85 |
86 | - 回调灵活:可选择当前或UI线程执行回调,开始结束、成败、上传、下载进度等都可监听。
87 |
88 | - 文件上传:支持单个、多个大文件上传。
89 |
90 | - 文件下载:支持文件、Bimtap下载及其进度通知。
91 |
92 | - 网络禁用:快速禁用一种、多种网络环境,比如指定禁用 2G,3G 。
93 |
94 | - 数据统计:链接、读取时长统计,以及流量统计。
95 |
96 | - 异常体系:统一、简明、清晰地抛出三类异常:客户端、网络、服务器,且异常都可精确细分。
97 |
98 | - GZIP压缩:Request, Response 自动 GZIP 压缩节省流量。
99 |
100 | - 自动重试:结合探测异常类型和当前网络状况,智能执行重试策略。
101 |
102 | - 自动重定向:基于 30X 状态的重试,且可设置最大次数防止过度跳转。
103 |
104 |
105 | ### 4. lite-http的整体架构是怎样的呀? (´ڡ`)
106 |
107 | ![lite-http架构图][6]
108 |
109 | 关于App架构,请看我另一篇文章分享:
110 | [怎样搭高质量的Android项目框架,框架的结构具体描述?][7]
111 |
112 | ### 5. 老湿,来点教学和分析带我飞呗? (◕‸◕)
113 |
114 | 好的 ◝‿◜ ,下面直接给你看,疗效好记得联系我,呵呵哒:
115 |
116 | [1. 初始化和初步使用][8]
117 |
118 | [2. 简化请求和非安全方法的使用][9]
119 |
120 | [3. 自动对象转化][10]
121 |
122 | [4. 自定义DataParser和Json序列化库的替换][11]
123 |
124 | [5. 文件、位图的上传和下载][12]
125 |
126 | [6. 禁用网络和流量、时间统计][13]
127 |
128 | [7. 重试和重定向][14]
129 |
130 | [8. 处理异常和取消请求][15]
131 |
132 | [9. POST方式的多种类型数据传输][16]
133 |
134 | [10. lite-http异步并发与调度策略][17]
135 |
136 | [11. 全局配置与参数设置详解][18]
137 |
138 | [12. 通过注解完成API请求][19]
139 |
140 | [13. 多层缓存机制及用法][20]
141 |
142 | [14. 回调监听器详解][21]
143 |
144 | [15. 并发调度控制器详解][22]
145 |
146 |
147 | [1]: http://shang.qq.com/wpa/qunwpa?idkey=492d63aaffb04b23d8dc4df21f6b594008cbe1a819978659cddab2dbc397684e
148 | [2]: http://shang.qq.com/wpa/qunwpa?idkey=19bf15b9c85ec15c62141dd00618f725e2983803cd2b48566fa0e94964ae8370
149 | [3]: https://zybuluo.com/liter/note/186533
150 | [4]: https://zybuluo.com/liter/note/186560
151 | [5]: https://zybuluo.com/liter/note/186533
152 | [6]: http://litesuits.com/imgs/lite-http-arch.png
153 | [7]: https://zybuluo.com/liter/note/186526
154 | [8]: https://zybuluo.com/liter/note/186560
155 | [9]: https://zybuluo.com/liter/note/186561
156 | [10]: https://zybuluo.com/liter/note/186565
157 | [11]: https://zybuluo.com/liter/note/186583
158 | [12]: https://zybuluo.com/liter/note/186756
159 | [13]: https://zybuluo.com/liter/note/186801
160 | [14]: https://zybuluo.com/liter/note/186860
161 | [15]: https://zybuluo.com/liter/note/186900
162 | [16]: https://zybuluo.com/liter/note/186965
163 | [17]: https://zybuluo.com/liter/note/186998
164 | [18]: https://zybuluo.com/liter/note/187016
165 | [19]: https://zybuluo.com/liter/note/187568
166 | [20]: https://zybuluo.com/liter/note/187894
167 | [21]: https://zybuluo.com/liter/note/187904
168 | [22]: https://zybuluo.com/liter/note/189537
--------------------------------------------------------------------------------
/docs/lite-http-10-异步并发与调度策略.md:
--------------------------------------------------------------------------------
1 | #Android网络通信框架LiteHttp 第十节:异步并发与调度策略
2 |
3 | 标签(空格分隔): litehttp2.x版本系列教程
4 |
5 | ---
6 | 官网: http://litesuits.com
7 |
8 | QQ群: 大群 47357508,二群 42960650
9 |
10 | 本系列文章面向android开发者,展示开源网络通信框架LiteHttp的主要用法,并讲解其关键功能的运作原理,同时传达了一些框架作者在日常开发中的一些最佳实践和经验。
11 |
12 | 本系列文章目录总览: https://zybuluo.com/liter/note/186513
13 |
14 | ---
15 |
16 | #第十节:LiteHttp之异步并发与调度策略
17 |
18 | lite-http 的异步执行和任务调度主要借助于 SmartExecutor 来完成的,关于 SmartExecutor 的介绍和使用后边会有专门的文章来讲解。
19 |
20 | lite-http 因此具备 SmartExecutor 的全部特性:
21 | >
22 | 可定义核心并发线程数,即同一时间并发的请求数量。
23 | >
24 | 可定义等待排队线程数,即超出核心并发数后可排队请求数量。
25 | >
26 | 可定义等待队列进入执行状态的策略:先来先执行,后来先执行。
27 | >
28 | 可定义等待队列满载后处理新请求的策略:
29 | >
30 | - 抛弃队列中最新的任务
31 | - 抛弃队列中最旧的任务
32 | - 抛弃当前新任务
33 | - 直接执行(阻塞当前线程)
34 | - 抛出异常(中断当前线程)
35 |
36 | lite-http拥有一个独立的 SmartExecutor 的实例,在一个 App 中 SmartExecutor 可以有多个实例,每个实例都有独立核心和等待线程数指标,每个实例都有独立的调度和满载处理策略,但它们 **共享一个线程池**。这种机制既满足不同木块对线程控制和任务调度的独立需求,又共享一个池资源。独立又共享,最大程度上节省资源,提升性能。
37 |
38 | 心急的朋友又要喊了: shut up, show me the code!
39 | ```java
40 | // Concurrent and Scheduling
41 |
42 | HttpConfig httpConfig = liteHttp.getConfig();
43 | // only one task can be executed at the same time
44 | httpConfig.setConcurrentSize(1);
45 | // at most two tasks be hold in waiting queue at the same time
46 | httpConfig.setWaitingQueueSize(2);
47 | // the last waiting task executed first
48 | httpConfig.setSchedulePolicy(SchedulePolicy.LastInFirstRun);
49 | // when task more than 3(current = 1, waiting = 2), new task will be discard.
50 | httpConfig.setOverloadPolicy(OverloadPolicy.DiscardCurrentTask);
51 | ```
52 | 上面的代码对lite-http进行了并发方面的参数设置:
53 | >
54 | 核心并发数为 1
55 | 等待队列数为 2
56 | 调度采用 后进先执行 策略
57 | 满载时采用 抛弃新任务 策略
58 |
59 | 然后测试:
60 | ```java
61 | for (int i = 0; i < 4; i++) {
62 | liteHttp.executeAsync(new StringRequest(url).setTag(i));
63 | }
64 |
65 | // submit order : 0 -> 1 -> 2 -> 3
66 | // task 0 is executing,
67 | // 1 and 2 is in waitting queue,
68 | // 3 was discarded.
69 | // real executed order: 0 -> 2 -> 1
70 | ```
71 | 上面的代码按顺序一次投入了四个请求,那么:
72 | >
73 | 投入任务顺序:0 -> 1 -> 2 -> 3
74 | 任务 0 立即执行
75 | 任务 1 和 2 在排队,按预定策略 2 后进,将先执行
76 | 任务 3 因为队列满载,按预定策略抛弃掉
77 | 实际执行顺序:0 -> 2 -> 1
78 |
79 | 对于 SmartExecutor,不论多少个实例,其控制指标和策略独立,始终共享一个池,避免掉多余开销。
80 |
81 | 理论上,**一个 App 只创建一个线程池** 就足够了,但是现在框架众多,有的独立精悍,有的功能众多,还是要提醒开发者,选用的框架最好知根知底、深入了解。不清楚里面什么机制,更是控制不了就会尴尬,到头来根本不知道自己的 App 里面有几个线程池。
82 |
83 |
84 |
85 | 开发者在构建自己的池子时要注意清闲时活跃线程不要多持,最好不要超过CPU数量,注意控制排队和满载策略,大量并发瞬间起来也能轻松应对。
86 |
87 | 另外,同时并发的线程数量不要过多,最好保持在CPU核数左右,过多了CPU时间片过多的轮转分配造成吞吐量降低,过少了不能充分利用CPU,并发数可以适当比CPU核数多一点没问题。
88 |
89 | 好了,本节先将这么多,更多并发姿势在关于 SmartExecutor 的文章里分享。
90 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/docs/lite-http-12-通过注解完成API请求.md:
--------------------------------------------------------------------------------
1 | #Android网络通信框架LiteHttp 第十二节:通过注解完成API请求
2 |
3 | 标签(空格分隔): litehttp2.x版本系列教程
4 |
5 | ---
6 | 官网: http://litesuits.com
7 |
8 | QQ群: 大群 47357508,二群 42960650
9 |
10 | 本系列文章面向android开发者,展示开源网络通信框架LiteHttp的主要用法,并讲解其关键功能的运作原理,同时传达了一些框架作者在日常开发中的一些最佳实践和经验。
11 |
12 | 本系列文章目录总览: https://zybuluo.com/liter/note/186513
13 |
14 | ---
15 | #第十二节:LiteHttp之通过注解完成API请求
16 |
17 | 本节强烈推荐通过 RichParamModel 方式构建请求,它大概是长这样子:
18 | ```java
19 | @HttpUri(loginUrl)
20 | class LoginParam extends HttpRichParamModel {
21 | public String name = "lucy";
22 | public String password = "123456";
23 | }
24 | liteHttp.executeAsync(new UserRichParam());
25 | ```
26 | 表示请求 loginUrl 这个地址,并传递 name 和 password 参数,返回用户 User 对象。
27 |
28 | 关于注解,还得从头说起:
29 |
30 | 在java模型自动转化那一节我们讲过,lite-http 可以把java对象转换为http请求的参数,需要该java类继承 HttpParamModel,实际上 HttpParamModel 还有一个拓展子类 HttpRichParamModel,拓展顾名思义是一个基于原来的增强,开发者连Request都不用写了,直接继承 HttpRichParamModel 通过注解来完成整个http请求的参数约定。
31 |
32 | ## 1. 简单参数 HttpParamModel
33 |
34 | 先看这段代码:
35 | ```java
36 | // Usage of Annotation
37 | public String userUrl = "http://litesuits.com/mockdata/user_get";
38 |
39 | @HttpUri(userUrl)
40 | @HttpMethod(HttpMethods.Get)
41 | @HttpID(1)
42 | @HttpCacheMode(CacheMode.CacheFirst)
43 | @HttpCacheExpire(value = 1, unit = TimeUnit.MINUTES)
44 | class UserAnnoParam implements HttpParamModel {
45 | public long id = 110;
46 | private String key = "aes";
47 | }
48 |
49 | liteHttp.executeAsync(new JsonRequest(new UserAnnoParam(), User.class) {}
50 | .setHttpListener(new HttpListener() {
51 | @Override
52 | public void onSuccess(User user, Response response) {
53 | HttpUtil.showTips(activity, "UserAnnoParam", user.toString());
54 | }
55 | }));
56 | ```
57 |
58 | 所见即所得,通过这些注解:
59 | >
60 | @HttpUri(userUrl)
61 | @HttpMethod(HttpMethods.Get)
62 | @HttpID(1)
63 | @HttpCacheMode(CacheMode.CacheFirst)
64 | @HttpCacheExpire(value = 1, unit = TimeUnit.MINUTES)
65 |
66 | 上面一段代码,完成了这样一次请求配置:
67 | >
68 | 请求地址为 userUrl
69 | 请求方式为 GET
70 | 请求ID为 1
71 | 请求优先使用缓存
72 | 请求缓存时间为1分钟
73 |
74 | ## 2. 扩展版参数HttpRichParamModel
75 |
76 | 再看一下拓展的参数类如何工作:
77 | ```java
78 | // Best Practice: HTTP Rich Param Model (It is simpler and More Useful)
79 |
80 | @HttpUri(userUrl)
81 | class UserRichParam extends HttpRichParamModel {
82 | public long id = 110;
83 | private String key = "aes";
84 | }
85 |
86 | // 一句话调用即可
87 | liteHttp.executeAsync(new UserRichParam());
88 | ```
89 |
90 | 可见,最后一句执行时连 Request 都没有创建,直接将参数投入执行。
91 | >
92 | 定义RichParam,可指定URL、参数、响应体三个关键事物:
93 | 请求地址: uerUrl
94 | 请求参数: id=110 & key=aes
95 | 请求响应: User
96 |
97 | 更多注解方式有:
98 | >
99 | @HttpSchemeHost("http://litesuits.com") // 定义scheme
100 | @HttpUri("/mockdata/user_get") // 定义uri 或者 path
101 | @HttpMethod(HttpMethods.Get) // 请求方式
102 | @HttpCharSet("UTF-8") // 请求编码
103 | @HttpTag("custom tag") // 打TAG
104 | @HttpCacheMode(CacheMode.CacheFirst) // 缓存模式
105 | @HttpCacheKey("custom-cache-key-name-by-myself") // 缓存文件名字
106 | @HttpCacheExpire(value = 1, unit = TimeUnit.MINUTES) // 缓存时间
107 | @HttpID(2) // 请求ID
108 | @HttpMaxRetry(3) // 重试次数
109 | @HttpMaxRedirect(5) // 重定向次数
110 |
111 | 此外,继承Rich Param的参数类还可以复写下面方法:
112 | >
113 | createHeaders : 创建header
114 | createQueryBuilder: 设置参数构建器
115 | createHttpListener: 创建监听器
116 | createHttpBody: 创建数据体
117 |
118 | createHttpBody是为POST、PUT等方式创建数据体,GET、DELETE等不需要,因其参数直接拼接到URL。
119 |
120 | ## 3. 最佳实践
121 | 最后,通过这句:
122 | > liteHttp.executeAsync(new UserRichParam());
123 |
124 | 可见 RichParamModel 是可以直接抛入执行的,这就将其和 Request 基本提升到了同一级别。
125 | 在我的 App 里,我是直接用 RichParamModel 的,因为它更直观简单,并且 RichParamModel 可以通过 set 方法设置监听器等参数,所以我也建议开发者使用这个进行请求配置。
126 |
127 | 强烈推荐通过 RichParamModel 方式构建请求。
128 |
129 |
--------------------------------------------------------------------------------
/docs/lite-http-13-多层缓存机制及用法.md:
--------------------------------------------------------------------------------
1 | #Android网络通信框架LiteHttp 第十三节:多层缓存机制及用法
2 |
3 | 标签(空格分隔): litehttp2.x版本系列教程
4 |
5 | ---
6 | 官网: http://litesuits.com
7 |
8 | QQ群: 大群 47357508,二群 42960650
9 |
10 | 本系列文章面向android开发者,展示开源网络通信框架LiteHttp的主要用法,并讲解其关键功能的运作原理,同时传达了一些框架作者在日常开发中的一些最佳实践和经验。
11 |
12 | 本系列文章目录总览: https://zybuluo.com/liter/note/186513
13 |
14 | ---
15 | #第十三节:LiteHttp之多层缓存机制及用法
16 |
17 | 先了解下什么是多级缓存,了解或做过图片加载框架的同学可能比较清楚,一般情况下第一级为闪存,第二级为外存,如果非要说第三级那么就是网络了,严格讲网络上的内容不算缓存。
18 |
19 | lite-http设计之时也考虑到了这些,因为大多数API请求信息体不大,几K就算数据量比较大的了,这些请求完全可以缓存到内存。而有些请求占用空间非常大,比如图片、音乐等文件,对于网络框架而言,这些不适合存储到闪存,而需要缓存到本地SD卡等外存设备。
20 |
21 | 如何构建可缓存请求,请看下面代码:
22 |
23 | ```java
24 | // Multi Cache Mechanism
25 |
26 | StringRequest cacheRequest = new StringRequest(url);
27 |
28 | cacheRequest.setCacheMode(CacheMode.CacheFirst);
29 | cacheRequest.setCacheExpire(30, TimeUnit.SECONDS);
30 | cacheRequest.setCacheDir("/sdcard/lite");
31 | cacheRequest.setCacheKey(null);
32 |
33 | cacheRequest.setHttpListener(new HttpListener() {
34 | @Override
35 | public void onSuccess(String html, Response response) {
36 | String title = response.isCacheHit() ? "Hit Cache(使用缓存)" : "No Cache(未用缓存)";
37 | HttpUtil.showTips(activity, title, html);
38 | }
39 | });
40 | liteHttp.executeAsync(cacheRequest);
41 | ```
42 |
43 | 主要代码为:
44 | >
45 | response.isCacheHit(): 判断是否命中缓存
46 | >
47 | setCacheExpire: 设置缓存有效时间,默认为-1,永久不超时。
48 | setCacheDir: 设置放置缓存的文件夹
49 | setCacheKey: 设置缓存文件名,不设置则框架自动产生。
50 | setCacheMode: 设置缓存类型,CacheMode有四种,默认NetOnly方式。
51 | >
52 | - NetOnly 即直接联网,不使用缓存;
53 | - NetFirst 优先网络获取,失败后取缓存;
54 | - CacheFirst 即优先用缓存,失败后连接网络;
55 | - CacheOnly 即只使用缓存,不连接网络。
56 |
57 |
58 | 另外,还有一种通过注解设置缓存方式:
59 |
60 | ```java
61 | @HttpUri(userUrl)
62 | @HttpCacheMode(CacheMode.CacheFirst)
63 | @HttpCacheExpire(value = 1, unit = TimeUnit.MINUTES)
64 | class UserAnnoParam implements HttpParamModel {
65 | public long id = 110;
66 | private String key = "aes";
67 | }
68 | ```
69 |
70 | 或者
71 | ```java
72 |
73 | // 其他更多注解还有:
74 | @HttpUri(userUrl) // 定义uri 或者 path
75 | @HttpCacheMode(CacheMode.CacheFirst) // 缓存模式
76 | @HttpCacheExpire(value = 1, unit = TimeUnit.MINUTES) // 缓存时间
77 | class TEST extends HttpRichParamModel { }
78 |
79 | liteHttp.executeAsync(new TEST());
80 | ```
81 |
82 | 另外,lite-http还提供了一下方法来清除缓存:
83 | >
84 | - 清除某个请求的缓存,包括闪存和文件缓存:
85 | liteHttp.cleanCacheForRequest(request)
86 | - 清除全部闪存缓存
87 | liteHttp.clearMemCache()
88 | - 删除当前缓存文件夹下面所有文件
89 | liteHttp.deleteCachedFiles()
90 |
91 |
92 | 好,本节至此完。
93 |
--------------------------------------------------------------------------------
/docs/lite-http-2-简化请求和非安全方法的使用.md:
--------------------------------------------------------------------------------
1 | # Android网络通信框架LiteHttp 第二节:简化请求和非安全方法的使用
2 |
3 | 标签(空格分隔): litehttp2.x版本系列教程
4 |
5 | ---
6 | 官网: http://litesuits.com
7 |
8 | QQ群: 大群 47357508,二群 42960650
9 |
10 | 本系列文章面向android开发者,展示开源网络通信框架LiteHttp的主要用法,并讲解其关键功能的运作原理,同时传达了一些框架作者在日常开发中的一些最佳实践和经验。
11 |
12 | 本系列文章目录总览: https://zybuluo.com/liter/note/186513
13 |
14 | ---
15 |
16 | #第二节:LiteHttp之简化请求和非安全方法的使用
17 |
18 | 方便测试,先随意定义一些合法的URL:
19 | ```java
20 | public static final String url = "http://baidu.com";
21 | public static final String httpsUrl = "https://baidu.com";
22 | public static final String userUrl = "http://litesuits.com/mockdata/user_get";
23 | ```
24 | ## 1. 简化的请求
25 |
26 | 发起同步请求时,部分请求可以被简化。
27 | GET方式获取API返回的String:
28 | ```java
29 | String html = liteHttp.get(url);
30 | ```
31 |
32 | GET方式直接获取Java Model:
33 | ```java
34 | User user = liteHttp.get(userUrl, User.class);
35 | ```
36 |
37 | POST方式获取String:
38 | ```java
39 | String result = liteHttp.post(new StringRequest(httpsUrl));
40 | ```
41 |
42 | HEAD方式获取头信息:
43 | ```java
44 | NameValuePair[] headers = liteHttp.head(new StringRequest(url));
45 | ```
46 |
47 | 等等...可自行查看源码了解更多。
48 |
49 | ## 2. 非安全的请求
50 |
51 | 有时候开发者在某种情况下需要抛出异常中断后面代码,或者某场景下需要自己捕获异常,那么需要发送非安全的请求。
52 |
53 | ```java
54 | // http scheme error
55 | try {
56 | Response response = liteHttp.executeOrThrow(new BytesRequest("haha://hehe"));
57 | // do something...
58 | } catch (HttpException e) {
59 | e.printStackTrace();
60 | }
61 |
62 | // java model translate error
63 | try {
64 | User user = liteHttp.performOrThrow(new JsonAbsRequest("http://thanku.love") {});
65 | } catch (final HttpException e) {
66 | e.printStackTrace();
67 | }
68 | ```
69 |
70 | ## 3. https 请求
71 |
72 | ```java
73 | liteHttp.executeAsync(new StringRequest(httpsUrl).setHttpListener(
74 | new HttpListener() {
75 | @Override
76 | public void onSuccess(String s, Response response) {
77 |
78 | }
79 | }
80 | ));
81 | ```
--------------------------------------------------------------------------------
/docs/lite-http-3-自动对象转化.md:
--------------------------------------------------------------------------------
1 | #Android网络通信框架LiteHttp 第三节:自动对象转化
2 |
3 | 标签(空格分隔): litehttp2.x版本系列教程
4 |
5 | ---
6 | 官网: http://litesuits.com
7 |
8 | QQ群: 大群 47357508,二群 42960650
9 |
10 | 本系列文章面向android开发者,展示开源网络通信框架LiteHttp的主要用法,并讲解其关键功能的运作原理,同时传达了一些框架作者在日常开发中的一些最佳实践和经验。
11 |
12 | 本系列文章目录总览: https://zybuluo.com/liter/note/186513
13 |
14 | ---
15 |
16 | #第三节:LiteHttp之自动对象转化
17 |
18 | 下面是一个真实有效的API地址:
19 | ```java
20 | public static final String userUrl = "http://litesuits.com/mockdata/user_get";
21 | ```
22 | 它的响应体是个Json结构的字符串:
23 | ```json
24 | {
25 | "api": "com.xx.get.userinfo",
26 | "v": "1.0",
27 | "result": {
28 | "code": 200,
29 | "message": "success"
30 | },
31 | "data": {
32 | "age": 18,
33 | "name": "qingtianzhu",
34 | "girl_friends": [
35 | "xiaoli",
36 | "fengjie",
37 | "lucy"
38 | ]
39 | }
40 | }
41 | ```
42 |
43 | ## 1. java对象转为http参数
44 | 假设是一个GET请求,就是说将参数拼接在URL里,类似:http://{userUrl}?id=168&key=md5,自动拼接参数的示范代码如下:
45 | ```java
46 | /**
47 | * Param Model: will be converted to: http://...?id=168&key=md5
48 | */
49 | class UserParam implements HttpParamModel {
50 | // static final property will be ignored.
51 | private static final long serialVersionUID = 123L;
52 | private long id;
53 | public String key;
54 | @NonHttpParam
55 | protected String ignored = "Ignored by @NonHttpParam ";
56 |
57 | public UserParam(long id, String key) {
58 | this.id = id;
59 | this.key = key;
60 | }
61 | }
62 |
63 | // build as http://{userUrl}?id=168&key=md5
64 | liteHttp.executeAsync(new StringRequest(userUrl, new UserParam(18, "md5"))
65 | .setHttpListener(new HttpListener() {
66 | @Override
67 | public void onSuccess(String data, Response response) {
68 | Log.i(TAG, "USER: " + data);
69 | }
70 | }));
71 | ```
72 | 上面示范了将UserParam对象转化为URL参数,并得到String响应的方式,注意:
73 |
74 | - static final 的字段将被忽略;
75 | - @NonHttpParam 标注的字段将被忽略;
76 | - private 等权限修饰符不影响字段转为参数;
77 | - 值为 null 的对象将被忽略,未赋值的基础数据类型传递默认值;
78 |
79 | ## 2. json string转为java对象
80 |
81 | ```java
82 | /**
83 | * Request Model : json string translate to user object
84 | */
85 | class UserRequest extends JsonAbsRequest {
86 | public UserRequest(String url, Http) {
87 | super(url);
88 | }
89 | }
90 |
91 | // build as http://{userUrl}?id=168&key=md5
92 | UserRequest userRequest = new UserRequest(userUrl, new UserParam(18, "md5"));
93 | userRequest.setHttpListener(new HttpListener() {
94 | @Override
95 | public void onSuccess(User user, Response response) {
96 | // data has been translated to user object
97 | }
98 | });
99 | liteHttp.executeAsync(userRequest);
100 | ```
101 | 上面示范了将UserParam对象转化为URL参数,并直接得到User响应对象的方式,注意:
102 |
103 | - 参数类 UserParam 实现 HttpParamModel
104 | - 请求类 UserRequest 继承 JsonAbsRequest,当然也可以简化为:
105 | ```java
106 | User user = liteHttp.executeAsync(new JsonAbsRequest(userUrl) {});
107 | ```
108 | - User类无要求,建议统一继承基类,比如这里的User:
109 | ```java
110 | /**
111 | * base model
112 | */
113 | public abstract class BaseModel implements Serializable {
114 | }
115 |
116 | /**
117 | * api model: base structure
118 | */
119 | public class ApiModel extends BaseModel {
120 | /**
121 | * 不变的部分:写在API基类中
122 | */
123 | private String api;
124 | private String v;
125 |
126 | protected int code;
127 | protected String message;
128 |
129 | /**
130 | * 变化的部分:使用泛型,数据类型的确认延迟到子类里。
131 | */
132 | protected T data;
133 |
134 | // getter setter toString 等方法已删减掉...
135 | }
136 |
137 | /**
138 | * response string will be converted to this model
139 | */
140 | public class User extends ApiModel {
141 |
142 | // 泛型设置:定义一个公共静态内部类(也可以定义外部类)
143 | public static class Data extends BaseModel{
144 | public int age;
145 | public String name;
146 | public ArrayList girl_friends;
147 |
148 | // getter setter toString 等方法已删减掉...
149 | }
150 | }
151 | ```
152 |
153 | Model Parameter String 之间的转化比较灵活,请各位玩家多看源码和案例,依据实际需求,挖掘更多玩法。
154 |
--------------------------------------------------------------------------------
/docs/lite-http-6-禁用网络和流量&耗时统计.md:
--------------------------------------------------------------------------------
1 | #Android网络通信框架LiteHttp 第六节:禁用网络和流量&耗时统计
2 |
3 | 标签(空格分隔): litehttp2.x版本系列教程
4 |
5 | ---
6 | 官网: http://litesuits.com
7 |
8 | QQ群: 大群 47357508,二群 42960650
9 |
10 | 本系列文章面向android开发者,展示开源网络通信框架LiteHttp的主要用法,并讲解其关键功能的运作原理,同时传达了一些框架作者在日常开发中的一些最佳实践和经验。
11 |
12 | 本系列文章目录总览: https://zybuluo.com/liter/note/186513
13 |
14 | ---
15 |
16 | #第六节:LiteHttp之禁用网络和流量&耗时统计
17 |
18 | ## 1. 禁用网络
19 |
20 | 开发者可以通过lite-http的config来设置禁用某种网络,比如我们将移动网络和wifi都禁用:
21 | ```java
22 | // disable some network
23 | HttpConfig config = liteHttp.getConfig();
24 |
25 | // must set context
26 | config.setContext(activity);
27 |
28 | // disable mobile(2G/3G/4G) and wifi network
29 | config.setDisableNetworkFlags(HttpConfig.FLAG_NET_DISABLE_MOBILE | HttpConfig.FLAG_NET_DISABLE_WIFI);
30 |
31 | liteHttp.executeAsync(new StringRequest(url).setHttpListener(new HttpListener() {
32 | @Override
33 | public void onSuccess(String s, Response response) {
34 | HttpUtil.showTips(activity, "LiteHttp2.0", s);
35 | }
36 |
37 | @Override
38 | public void onFailure(HttpException e, Response response) {
39 | HttpUtil.showTips(activity, "LiteHttp2.0", e.toString());
40 | }
41 | }));
42 | ```
43 | 这样不管是sim卡网络还是无线wifi下发送请求都会失败,onFailure会触发。
44 | 恢复可用状态:
45 | ```java
46 | // enable network
47 | HttpConfig config = liteHttp.getConfig();
48 |
49 | // enable all
50 | config.setDisableNetworkFlags(HttpConfig.FLAG_NET_DISABLE_NONE);
51 | ```
52 |
53 | ## 2. 流量和耗时统计
54 |
55 | 只需要从配置打开统计开关即可:
56 | ```java
57 | // Traffic/Time Statistics
58 | String picUrl = "http://pic.33.la/20140403sj/1638.jpg";
59 |
60 | // turn on
61 | liteHttp.getConfig().setDoStatistics(true);
62 |
63 | liteHttp.executeAsync(new FileRequest(picUrl).setHttpListener(new HttpListener() {
64 | @Override
65 | public void onSuccess(File file, Response response) {
66 | String msg = "This request take time:" + response.getUseTime()
67 | + ", readed length:" + response.getReadedLength();
68 | msg += " Global " + liteHttp.getStatisticsInfo();
69 | HttpUtil.showTips(activity, "LiteHttp2.0", msg);
70 | }
71 |
72 | @Override
73 | public void onFailure(HttpException e, Response response) {
74 | HttpUtil.showTips(activity, "LiteHttp2.0", e.toString());
75 | }
76 | }));
77 | ```
78 | 更多数据统计:
79 | >
80 | response.getRedirectTimes(); // 重定向的次数
81 | response.getRetryTimes(); // 重试的次数
82 | response.getUseTime(); // 本次请求耗时
83 | response.getContentLength(); // header中的数据长度(Content-Length)
84 | response.getReadedLength(); // 实际读取的数据长度
85 |
86 | 整体数据统计:
87 | >
88 | StatisticsInfo sta = liteHttp.getStatisticsInfo();
89 | sta.getConnectTime(); // litehttp 实例化后所有请求耗时累计
90 | sta.getDataLength(); // litehttp 实例化后读取数据长度累计
91 |
92 |
--------------------------------------------------------------------------------
/docs/lite-http-7-重试和重定向.md:
--------------------------------------------------------------------------------
1 | #Android网络通信框架LiteHttp 第七节:重试和重定向
2 |
3 | 标签(空格分隔): litehttp2.x版本系列教程
4 |
5 | ---
6 | 官网: http://litesuits.com
7 |
8 | QQ群: 大群 47357508,二群 42960650
9 |
10 | 本系列文章面向android开发者,展示开源网络通信框架LiteHttp的主要用法,并讲解其关键功能的运作原理,同时传达了一些框架作者在日常开发中的一些最佳实践和经验。
11 |
12 | 本系列文章目录总览: https://zybuluo.com/liter/note/186513
13 |
14 | ---
15 | #第七节:LiteHttp之重试和重定向
16 |
17 | ## 1. 重试和重定向
18 |
19 | 先准备一个可以重定向的地址:
20 | ```java
21 | public String redirectUrl = "http://www.baidu.com/link?url=Lqc3GptP8u05JCRDsk0jqsAvIZh9WdtO_RkXYMYRQEm";
22 | ```
23 | 设置最大跳转和重试次数即可,然后开跳:
24 | ```java
25 | // Retry/Redirect
26 |
27 | // make request
28 | StringRequest redirect = new StringRequest(redirectUrl)
29 | .setMaxRetryTimes(1) // maximum retry times
30 | .setMaxRedirectTimes(5) // maximum redirect times
31 | .setHttpListener(new HttpListener() {
32 |
33 | @Override
34 | public void onRedirect(AbstractRequest request, int max, int times) {
35 | Toast.makeText(activity, "Redirect max num: " + max + " , times: " + times
36 | + "\n GO-TO: " + request.getUri(), Toast.LENGTH_LONG).show();
37 | }
38 |
39 | @Override
40 | public void onRetry(AbstractRequest request, int max, int times) {
41 | Toast.makeText(activity, "Retry Now! max num: " + max + " , times: " + times
42 | , Toast.LENGTH_LONG).show();
43 |
44 | }
45 |
46 | @Override
47 | public void onSuccess(String s, Response response) {
48 | HttpUtil.showTips(activity, "LiteHttp2.0", "Content Length: " + s.length());
49 | }
50 | });
51 |
52 | liteHttp.executeAsync(redirect);
53 | ```
54 | 也可以设置全局重试和重定向次数:
55 | ```java
56 | // default retry times
57 | liteHttp.getConfig().setDefaultMaxRetryTimes(2);
58 | // default redirect times
59 | liteHttp.getConfig().setDefaultMaxRedirectTimes(4);
60 | ```
61 | 如果请求本身设置了最大重试和重定向次数,以请求本身设置为准,如果未设置,则取全局默认值。
62 |
63 | ## 2. 关于重试的更多知识
64 |
65 | 重试出现的原因比较复杂或隐晦,网络状态不良时可能会触发,测试中难以必现。
66 |
67 | 当出现以下异常时,立即结束不作重试:
68 | >
69 | UnknownHostException
70 | FileNotFoundException
71 | SSLException
72 | ConnectException
73 |
74 | 当出现以下异常时,重试发生可能性较大:
75 | >
76 | NoHttpResponseException
77 | SocketException
78 | SocketTimeoutException
79 | ConnectTimeoutException
80 |
81 | 当未传入context时,线程睡眠指定时间,睡眠时间可以在config中设置,默认时间3000毫秒:
82 | >
83 | // default retry waitting time
84 | liteHttp.getConfig().setForRetry(1500, false);
85 |
86 | 传入context时,lite-http便可以自己判断网络状态,如果网络是连接中的线程不作睡眠立即重试,当系统网络处于连接中、扫描等状态时,睡眠等待指定时间后重试。
87 |
88 | ## 3. 关于重定向的原理和过程
89 |
90 | 当请求状态码为 **30x** 时,应该处理重定向的情况。
91 | 获取 header 中 location 字段的值,即为重定向新地址。
92 | 一般情况下新地址可能不包含 scheme 和 host 信息,因此需要我们自己拼接。
93 | 当重试大于最大次数,给予抛出异常处理。
94 |
95 | 框架主要代码如下:
96 | ```java
97 | if (response.getRedirectTimes() < maxRedirectTimes) {
98 | // get the location header to find out where to redirect to
99 | Header locationHeader = ares.getFirstHeader(Consts.REDIRECT_LOCATION);
100 | if (locationHeader != null) {
101 | String location = locationHeader.getValue();
102 | if (location != null && location.length() > 0) {
103 | if (!location.toLowerCase().startsWith("http")) {
104 | URI uri = new URI(request.getFullUri());
105 | URI redirect = new URI(uri.getScheme(), uri.getHost(), location, null);
106 | location = redirect.toString();
107 | }
108 | response.setRedirectTimes(response.getRedirectTimes() + 1);
109 | request.setUri(location);
110 | if (HttpLog.isPrint) {
111 | HttpLog.i(TAG, "Redirect to : " + location);
112 | }
113 | if (listener != null) {
114 | listener.notifyCallRedirect(request, maxRedirectTimes, response.getRedirectTimes());
115 | }
116 | connectWithRetries(request, response);
117 | return;
118 | }
119 | }
120 | throw new HttpServerException(httpStatus);
121 | } else {
122 | throw new HttpServerException(ServerException.RedirectTooMuch);
123 | }
124 | ```
125 |
126 | 更多知识,多看源码,抽空造个小轮子,来得更直接。
--------------------------------------------------------------------------------
/docs/lite-http-引言.md:
--------------------------------------------------------------------------------
1 | # LiteHttp 引言:开发者为什么要选LiteHttp?
2 |
3 | 标签(空格分隔): litehttp2.x版本系列教程
4 |
5 | ---
6 | 官网: http://litesuits.com
7 | QQ群: 大群 47357508,二群 42960650
8 |
9 | 本系列文章目录总览: https://zybuluo.com/liter/note/186513
10 |
11 | ---
12 |
13 | # 开发者为什么要选LiteHttp?
14 |
15 | 我们来看一个普通android网络应用上,最基础的http连接和json解析方式,一个简单例子。
16 |
17 | 从服务器获取 id=168 的用户的信息,User 的 json 结构:
18 | ```json
19 | {
20 | "api": "com.xx.get.userinfo",
21 | "v": "1.0",
22 | "result": {
23 | "code": 200,
24 | "message": "success"
25 | },
26 | "data": {
27 | "age": 18,
28 | "name": "qingtianzhu",
29 | "girl_friends": [
30 | "xiaoli",
31 | "fengjie",
32 | "lucy"
33 | ]
34 | }
35 | }
36 | ```
37 |
38 | api, v, result为必备基础信息,完成这个任务一般分三步:
39 |
40 | **1. 组织api的url地址和参数(简单),比如:**
41 | ```java
42 | String url = "http://litesuits.github.io/mockdata/user?userid=168";
43 | ```
44 |
45 | **2. http连接网络获取api信息(封装后还算简单),典型代码:**
46 | ```java
47 | /**
48 | * 关闭流顺序:先打开的后关闭;被依赖的后关闭。
49 | * @return string info
50 | */
51 | public static String sendHttpRequst(String apiUrl) {
52 | HttpURLConnection conn = null;
53 | InputStream is = null;
54 | ByteArrayOutputStream baos = null;
55 | try {
56 | URL url = new URL(apiUrl);
57 | conn = (HttpURLConnection) url.openConnection();
58 | conn.connect();
59 | is = conn.getInputStream();
60 | int len = conn.getContentLength();
61 | if (len < 1) len = 1024;
62 | baos = new ByteArrayOutputStream(len);
63 | byte[] buffer = new byte[1024];
64 | len = 0;
65 | while ((len = is.read(buffer)) != -1) {
66 | baos.write(buffer, 0, len);
67 | }
68 | return baos.toString();
69 | } catch (MalformedURLException e) {
70 | e.printStackTrace();
71 | } catch (IOException e) {
72 | e.printStackTrace();
73 | } finally {
74 | try {
75 | if (baos != null) baos.close();
76 | if (is != null) is.close();
77 | } catch (IOException e) {
78 | e.printStackTrace();
79 | }
80 | if (conn != null) conn.disconnect();
81 | }
82 | return null;
83 | }
84 | ```
85 |
86 | **3. 解析服务器反馈的string(比较头疼):**
87 | ```java
88 | public static User parseJsonToUser(String json) {
89 | User user = new User();
90 | if (json != null) {
91 | try {
92 | JSONObject jsonObj = new JSONObject(json);
93 | JSONObject result = jsonObj.optJSONObject("result");
94 | JSONObject data = jsonObj.optJSONObject("data");
95 | JSONArray arr = null;
96 | if (data != null) arr = data.optJSONArray("girl_friends");
97 | user.result = new User.Result();
98 | user.data = new User.UserInfo();
99 | user.data.girl_friends = new ArrayList();
100 | if (jsonObj != null) {
101 | user.api = jsonObj.optString("api");
102 | user.v = jsonObj.optString("v");
103 | }
104 | if (result != null) {
105 | user.result.code = result.optInt("code");
106 | user.result.message = result.optString("message");
107 | }
108 | if (data != null) {
109 | user.data.age = data.optInt("age");
110 | user.data.name = data.optString("name");
111 | }
112 | if (arr != null) {
113 | for (int i = 0, size = arr.length(); i < size; i++) {
114 | user.data.girl_friends.add(arr.optString(i));
115 | }
116 | }
117 | } catch (JSONException e) {
118 | e.printStackTrace();
119 | }
120 | }
121 | return user;
122 | }
123 | ```
124 |
125 | 那么我们看到第3步在User这个类仅仅有3个属性的情况下,就写了约40行代码,如果User有几十个属性,应用中又有几十个类型User的Model,那么代码量将会指数级暴增,这种方式相对会耗费较大的劳动力。
126 |
127 | **那么,就此转入正题**
128 |
129 | 看看lite-http是怎么完成这个任务的:
130 | ```java
131 | User user = liteHttp.get(url, User.class);
132 | ```
133 | Github地址:https://github.com/litesuits/android-lite-http
134 |
135 | 项目中有20+个使用案例(Samples),带你飞。
136 |
--------------------------------------------------------------------------------
/downloads/gson-2.3.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/downloads/gson-2.3.jar
--------------------------------------------------------------------------------
/downloads/lite-go-1.0.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/downloads/lite-go-1.0.0.jar
--------------------------------------------------------------------------------
/downloads/lite-http-3.0.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/downloads/lite-http-3.0.0.jar
--------------------------------------------------------------------------------
/downloads/lite-http-3.0.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/downloads/lite-http-3.0.1.jar
--------------------------------------------------------------------------------
/downloads/lite-http-3.1.3.6.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/downloads/lite-http-3.1.3.6.jar
--------------------------------------------------------------------------------
/downloads/并发需要依赖lite-go组件.md:
--------------------------------------------------------------------------------
1 | 并发需要依赖lite-go组件
2 | Json解析默认使用Google的Gson库,可以通过Json.set(Json fastJsonImpl)自己设置为FastJson等类库解析。
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/litehttp-sample/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/litehttp-sample/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "23.0.2"
6 |
7 | defaultConfig {
8 | applicationId "com.litesuits.http.sample"
9 | minSdkVersion 9
10 | targetSdkVersion 22
11 | versionCode 1
12 | versionName "1.0"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | // compile fileTree(dir: 'libs', include: ['*.jar'])
24 | testCompile 'junit:junit:4.12'
25 | compile project(':litehttp')
26 | compile project(':apache-client')
27 | }
28 |
--------------------------------------------------------------------------------
/litehttp-sample/libs/fastjson-1.2.5.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/litehttp-sample/libs/fastjson-1.2.5.jar
--------------------------------------------------------------------------------
/litehttp-sample/src/androidTest/java/com/litesuits/http/sample/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.sample;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/litehttp-sample/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/litehttp-sample/src/main/java/com/litesuits/http/custom/CustomJSONParser.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.custom;
2 |
3 | import com.litesuits.http.parser.MemCacheableParser;
4 | import org.json.JSONException;
5 | import org.json.JSONObject;
6 |
7 | import java.io.IOException;
8 | import java.io.InputStream;
9 |
10 | /**
11 | * parse stream to JSONObject
12 | */
13 | public class CustomJSONParser extends MemCacheableParser {
14 | String json;
15 |
16 | /**
17 | * 实现远程网络流解析
18 | */
19 | @Override
20 | protected JSONObject parseNetStream(InputStream stream, long totalLength,
21 | String charSet) throws IOException {
22 | return streamToJson(stream, totalLength, charSet);
23 | }
24 |
25 | /**
26 | * 实现本地文件流解析
27 | */
28 | @Override
29 | protected JSONObject parseDiskCache(InputStream stream, long length) throws IOException {
30 | return streamToJson(stream, length, charSet);
31 | }
32 |
33 | /**
34 | * 实现文件缓存
35 | */
36 | @Override
37 | protected boolean tryKeepToCache(JSONObject data) throws IOException {
38 | return keepToCache(json);
39 | }
40 |
41 | /**
42 | * 1. 将 stream 转换为 String
43 | * 2. String 转为 JSONObject
44 | */
45 | protected JSONObject streamToJson(InputStream is, long length, String charSet) throws IOException {
46 | this.json = streamToString(is, length, charSet);
47 | try {
48 | return new JSONObject(json);
49 | } catch (JSONException e) {
50 | e.printStackTrace();
51 | }
52 | return null;
53 | }
54 | }
--------------------------------------------------------------------------------
/litehttp-sample/src/main/java/com/litesuits/http/custom/FastJson.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.custom;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import com.litesuits.http.data.Json;
5 |
6 | import java.lang.reflect.Type;
7 |
8 | public class FastJson extends Json {
9 | private static final String TAG = FastJson.class.getSimpleName();
10 |
11 | @Override
12 | public String toJson(Object src) {
13 | return JSON.toJSONString(src);
14 | }
15 |
16 | @Override
17 | public T toObject(String json, Class claxx) {
18 | return JSON.parseObject(json, claxx);
19 | }
20 |
21 | @Override
22 | public T toObject(String s, Type type) {
23 | return JSON.parseObject(s, type);
24 | }
25 |
26 | @Override
27 | public T toObject(byte[] bytes, Class claxx) {
28 | return JSON.parseObject(bytes, claxx);
29 | }
30 | }
--------------------------------------------------------------------------------
/litehttp-sample/src/main/java/com/litesuits/http/custom/MyHttpExceptHandler.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.custom;
2 |
3 | import android.app.Activity;
4 | import com.litesuits.http.data.HttpStatus;
5 | import com.litesuits.http.exception.*;
6 | import com.litesuits.http.exception.handler.HttpExceptionHandler;
7 | import com.litesuits.http.utils.HttpUtil;
8 |
9 | public class MyHttpExceptHandler extends HttpExceptionHandler {
10 | private Activity activity;
11 |
12 | public MyHttpExceptHandler(Activity activity) {
13 | this.activity = activity;
14 | }
15 |
16 | @Override
17 | protected void onClientException(HttpClientException e, ClientException type) {
18 | switch (e.getExceptionType()) {
19 | case UrlIsNull:
20 | break;
21 | case ContextNeeded:
22 | // some action need app context
23 | break;
24 | case PermissionDenied:
25 | break;
26 | case SomeOtherException:
27 | break;
28 | }
29 | HttpUtil.showTips(activity, "LiteHttp2.0", "Client Exception:\n" + e.toString());
30 | activity = null;
31 | }
32 |
33 | @Override
34 | protected void onNetException(HttpNetException e, NetException type) {
35 | switch (e.getExceptionType()) {
36 | case NetworkNotAvilable:
37 | break;
38 | case NetworkUnstable:
39 | // maybe retried but fail
40 | break;
41 | case NetworkDisabled:
42 | break;
43 | default:
44 | break;
45 | }
46 | HttpUtil.showTips(activity, "LiteHttp2.0", "Network Exception:\n" + e.toString());
47 | activity = null;
48 | }
49 |
50 | @Override
51 | protected void onServerException(HttpServerException e, ServerException type,
52 | HttpStatus status) {
53 | switch (e.getExceptionType()) {
54 | case ServerInnerError:
55 | // status code 5XX error
56 | break;
57 | case ServerRejectClient:
58 | // status code 4XX error
59 | break;
60 | case RedirectTooMuch:
61 | break;
62 | default:
63 | break;
64 | }
65 | HttpUtil.showTips(activity, "LiteHttp2.0", "Server Exception:\n" + e.toString());
66 | activity = null;
67 | }
68 | }
--------------------------------------------------------------------------------
/litehttp-sample/src/main/java/com/litesuits/http/model/ApiModel.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.model;
2 |
3 | /**
4 | * @author MaTianyu @http://litesuits.com
5 | * @date 2015-10-03
6 | */
7 | public class ApiModel extends BaseModel {
8 |
9 | /**
10 | * 不变的部分:写在API基类中
11 | */
12 | public String api;
13 | public String v;
14 |
15 | public int code;
16 | public String message;
17 |
18 | /**
19 | * 变化的部分:使用泛型,数据类型的确认延迟到子类里。
20 | */
21 | public T data;
22 |
23 | public String getApi() {
24 | return api;
25 | }
26 |
27 | public ApiModel setApi(String api) {
28 | this.api = api;
29 | return this;
30 | }
31 |
32 | public String getV() {
33 | return v;
34 | }
35 |
36 | public ApiModel setV(String v) {
37 | this.v = v;
38 | return this;
39 | }
40 |
41 | public int getCode() {
42 | return code;
43 | }
44 |
45 | public ApiModel setCode(int code) {
46 | this.code = code;
47 | return this;
48 | }
49 |
50 | public String getMessage() {
51 | return message;
52 | }
53 |
54 | public ApiModel setMessage(String message) {
55 | this.message = message;
56 | return this;
57 | }
58 |
59 | public T getData() {
60 | return data;
61 | }
62 |
63 | public ApiModel setData(T data) {
64 | this.data = data;
65 | return this;
66 | }
67 |
68 | @Override
69 | public String toString() {
70 | return "ApiModel{" +
71 | "api='" + api + '\'' +
72 | ", v='" + v + '\'' +
73 | ", code=" + code +
74 | ", message='" + message + '\'' +
75 | ", data=" + data +
76 | "} ";
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/litehttp-sample/src/main/java/com/litesuits/http/model/BaseModel.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.model;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * base model
7 | */
8 | public abstract class BaseModel implements Serializable {}
--------------------------------------------------------------------------------
/litehttp-sample/src/main/java/com/litesuits/http/model/User.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.model;
2 |
3 | import java.util.ArrayList;
4 |
5 | /**
6 | * response string will be converted to this model
7 | */
8 | public class User extends ApiModel {
9 |
10 | public static class Data extends BaseModel{
11 | private int age;
12 | private String name;
13 | private ArrayList girl_friends;
14 |
15 | public int getAge() {
16 | return age;
17 | }
18 |
19 | public Data setAge(int age) {
20 | this.age = age;
21 | return this;
22 | }
23 |
24 | public String getName() {
25 | return name;
26 | }
27 |
28 | public Data setName(String name) {
29 | this.name = name;
30 | return this;
31 | }
32 |
33 | public ArrayList getGirl_friends() {
34 | return girl_friends;
35 | }
36 |
37 | public Data setGirl_friends(ArrayList girl_friends) {
38 | this.girl_friends = girl_friends;
39 | return this;
40 | }
41 |
42 | @Override
43 | public String toString() {
44 | return "Data{" +
45 | "age=" + age +
46 | ", name='" + name + '\'' +
47 | ", girl_friends=" + girl_friends +
48 | "} " ;
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/litehttp-sample/src/main/java/com/litesuits/http/model/api/RichParam.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.model.api;
2 |
3 | import com.litesuits.http.annotation.HttpCacheExpire;
4 | import com.litesuits.http.annotation.HttpCacheMode;
5 | import com.litesuits.http.annotation.HttpMethod;
6 | import com.litesuits.http.annotation.HttpUri;
7 | import com.litesuits.http.model.User;
8 | import com.litesuits.http.request.content.HttpBody;
9 | import com.litesuits.http.request.content.UrlEncodedFormBody;
10 | import com.litesuits.http.request.param.CacheMode;
11 | import com.litesuits.http.request.param.HttpMethods;
12 | import com.litesuits.http.request.param.HttpRichParamModel;
13 | import com.litesuits.http.request.query.ModelQueryBuilder;
14 | import com.litesuits.http.request.query.SimpleQueryBuilder;
15 | import com.litesuits.http.sample.MainActivity;
16 |
17 | import java.util.concurrent.TimeUnit;
18 |
19 | /**
20 | * POST request, HTTP body:UrlEncodedForm: [id=000&key=xxx]
21 | * use cache
22 | */
23 | @HttpUri(MainActivity.userUrl)
24 | @HttpMethod(HttpMethods.Get)
25 | @HttpCacheMode(CacheMode.CacheFirst)
26 | @HttpCacheExpire(value = 10, unit = TimeUnit.SECONDS)
27 | public class RichParam extends HttpRichParamModel {
28 |
29 | private static final ModelQueryBuilder MODEL_QUERY_BUILDER = new SimpleQueryBuilder();
30 |
31 | public long id;
32 | public String key;
33 |
34 | public RichParam(long id, String key) {
35 | this.id = id;
36 | this.key = key;
37 | }
38 |
39 | @Override
40 | protected HttpBody createHttpBody() {
41 | return new UrlEncodedFormBody(getModelQueryBuilder().buildPrimaryPairSafely(this));
42 | }
43 |
44 | @Override
45 | protected ModelQueryBuilder createQueryBuilder() {
46 | return MODEL_QUERY_BUILDER;
47 | }
48 | }
--------------------------------------------------------------------------------
/litehttp-sample/src/main/java/com/litesuits/http/model/api/UserParam.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.model.api;
2 |
3 | import com.litesuits.http.request.param.HttpParam;
4 | import com.litesuits.http.request.param.HttpParamModel;
5 | import com.litesuits.http.request.param.NonHttpParam;
6 |
7 | /**
8 | * Param Model: will be converted to: http://...?id=168&key=md5
9 | */
10 | public class UserParam implements HttpParamModel {
11 | // static final property will be ignored.
12 | private static final long serialVersionUID = 2451716801614350437L;
13 |
14 | private String uri;
15 |
16 | @HttpParam("id")
17 | private long id;
18 |
19 | public String key;
20 |
21 | @NonHttpParam// lite http ignore
22 | private transient String beIgnored = "Ignored by @NonHttpParam ";
23 |
24 | public UserParam(long id, String key) {
25 | this.id = id;
26 | this.key = key;
27 | }
28 | }
--------------------------------------------------------------------------------
/litehttp-sample/src/main/java/com/litesuits/http/sample/Test.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.sample;
2 |
3 | /**
4 | * @author 氢一 @http://litesuits.com
5 | * @date 2016-06-16
6 | */
7 |
8 | public class Test {
9 | public static void main(String[] args) {
10 | String s = null;
11 | String b = null;
12 | String sb = s + b;
13 | System.out.println(sb);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/litehttp-sample/src/main/res/drawable/selector_list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
6 |
7 |
8 |
9 | -
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/litehttp-sample/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
18 |
19 |
23 |
24 |
25 |
33 |
34 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/litehttp-sample/src/main/res/layout/list_item.xml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
--------------------------------------------------------------------------------
/litehttp-sample/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/litehttp-sample/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/litehttp-sample/src/main/res/values-zh/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | LiteHttp 3
4 | LiteLib: HTTP-V3
5 | 通过日志和源码看详情.
6 |
7 |
8 | - 0. 快速配置(可忽略)
9 | - 1. 发起异步请求
10 | - 2. 发起同步请求
11 | - 3. 同步请求简化
12 | - 4. 可抛出异常的请求
13 | - 5. HTTPS请求
14 | - 6. 全自动模型转换
15 | - 7. 自定义数据解析
16 | - 8. 替换Json序列化库
17 | - 9. 文件、位图下载
18 | - 10. 文件上传
19 | - 11. 禁用网络
20 | - 12. 流量、时长统计
21 | - 13. 重试和重定向
22 | - 14. 最佳实践:异常处理
23 | - 15. 最佳实践:取消请求
24 |
25 | - 16. POST多形态数据
26 | - 17. 并发与调度策略
27 | - 18. 参数配置详解
28 | - 19. 使用注解
29 | - 20. 双层缓存机制
30 | - 21. 回调机制详解
31 | - 22. 最佳实践:使用SmartExecutor
32 | - 23. 最佳实践:全自动转换复杂对象
33 | - 24. 最佳实践:使用富 HTTP 参数
34 |
35 |
36 |
37 |
38 | - 1. 字符串上传
39 | - 2. UrlEncodedForm上传
40 | - 3. 对象自动转JSON上传
41 | - 4. 对象序列化后上传
42 | - 5. 字节上传
43 | - 6. 单文件上传
44 | - 7. 单输入流上传
45 | - 8. 多文件(表单)上传
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/litehttp-sample/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/litehttp-sample/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/litehttp-sample/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | LiteHttp 3
3 | LiteLib: HTTP-V3
4 | see more via code and log.
5 |
6 | - 0. Quickly Config(Can be Ignored)
7 | - 1. Asynchronous Request
8 | - 2. Synchronous Request
9 | - 3. Simple Synchronous Request
10 | - 4. Exception Thrown Request
11 | - 5. HTTPS Reqeust
12 | - 6. Automatic Model Conversion
13 | - 7. Custom Data Parser
14 | - 8. Replace Json Library
15 | - 9. File/Bitmap Download
16 | - 10. File Upload
17 | - 11. Disable Some Network
18 | - 12. Traffic/Time Statistics
19 | - 13. Retry/Redirect
20 | - 14. Best Practice: Exception Handling
21 | - 15. Best Practice: Cancel Request
22 |
23 | - 16. POST Multi-Form Data
24 | - 17. Concurrent and Scheduling
25 | - 18. Detail of Config
26 | - 19. Usage of Annotation
27 | - 20. Multi Cache Mechanism
28 | - 21. CallBack Mechanism
29 | - 22. Best Practice: SmartExecutor
30 | - 23. Best Practice: Auto-Conversion of Complex Model
31 | - 24. Best Practice: HTTP Rich Param Model
32 |
33 |
34 |
35 | - 1. String Data
36 | - 2. UrlEncodedForm Data
37 | - 3. Json Data
38 | - 4. Serializable Data
39 | - 5. ByteArray Data
40 | - 6. File
41 | - 7. InputStream
42 | - 8. Multipart Entity Data
43 |
44 |
45 |
--------------------------------------------------------------------------------
/litehttp-sample/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/litehttp-sample/src/test/java/com/litesuits/http/sample/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.sample;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 | assertEquals(4, 2 + 2);
14 | }
15 | }
--------------------------------------------------------------------------------
/litehttp/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/litehttp/build.gradle:
--------------------------------------------------------------------------------
1 | import proguard.gradle.ProGuardTask
2 |
3 | apply plugin: 'com.android.library'
4 |
5 |
6 | def liteHttpVersion = '3.1.3.6'
7 |
8 |
9 | android {
10 | compileSdkVersion 22
11 | buildToolsVersion '23.0.3'
12 |
13 | defaultConfig {
14 | minSdkVersion 9
15 | targetSdkVersion 22
16 | versionCode 4
17 | versionName liteHttpVersion
18 | }
19 | buildTypes {
20 | release {
21 | minifyEnabled false
22 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 | }
26 |
27 | dependencies {
28 | compile fileTree(dir: 'libs', include: ['*.jar'])
29 | testCompile 'junit:junit:4.12'
30 | }
31 |
32 | task cleanJars(type: Delete) {
33 | delete 'build/libs/*.*'
34 | }
35 |
36 | task cleanBuildDir(type: Delete) {
37 | delete rootProject.buildDir
38 | }
39 |
40 | def jarPath = 'build/libs/';
41 | def jarName = 'lite-http-' + liteHttpVersion + '.jar';
42 | def jarProName = 'lite-http-pro-' + liteHttpVersion + '.jar';
43 |
44 | task makeJar(type: Jar, dependsOn: ['assembleRelease']) {
45 | archiveName jarName;
46 | destinationDir = file('build/libs')
47 | from('build/intermediates/classes/release/')
48 | exclude('test/', 'BuildConfig.class', 'R.class', 'R\$*.class', 'META-INF/')
49 | }
50 |
51 | def androidSDKDir = plugins.getPlugin('com.android.library').sdkHandler.getSdkFolder()
52 | def androidJarDir = androidSDKDir.toString() + '/platforms/' + android.compileSdkVersion + '/android.jar'
53 |
54 | task makeProguardJar(type: ProGuardTask, dependsOn: ['makeJar']) {
55 | libraryjars(androidJarDir)
56 | configuration 'proguard-rules.pro'
57 | injars(jarPath + jarName)
58 | outjars(jarPath + jarProName)
59 | }
60 |
61 |
62 |
--------------------------------------------------------------------------------
/litehttp/libs/fastjson-1.2.5.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/litehttp/libs/fastjson-1.2.5.jar
--------------------------------------------------------------------------------
/litehttp/libs/gson-2.3.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/litehttp/libs/gson-2.3.jar
--------------------------------------------------------------------------------
/litehttp/libs/lite-go-1.0.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/litehttp/libs/lite-go-1.0.0.jar
--------------------------------------------------------------------------------
/litehttp/libs/lite-http-3.1.3.5.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/litehttp/libs/lite-http-3.1.3.5.jar
--------------------------------------------------------------------------------
/litehttp/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/matianyu/develop/android/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 | -optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*
19 | -optimizationpasses 7
20 | -allowaccessmodification
21 | -dontpreverify
22 |
23 | # The remainder of this file is identical to the non-optimized version
24 | # of the Proguard configuration file (except that the other file has
25 | # flags to turn off optimization).
26 |
27 | -dontusemixedcaseclassnames
28 | -dontskipnonpubliclibraryclasses
29 | -verbose
30 |
31 | # 使用注解
32 | -keepattributes *Annotation*,Signature,Exceptions
33 |
34 | # 保持混淆时类的实名及行号(--------------- 调试时打开 --------------)
35 | #-keepattributes SourceFile,LineNumberTable
36 |
37 | # 开发者需要调用,不可以混淆
38 | -keep public class com.litesuits.http.* { *; }
39 | -keep public class com.litesuits.http.response.Response { *; }
40 | -keep public class com.litesuits.http.utils.HttpUtil { *; }
41 | -keep public class com.litesuits.http.annotation.* { *; }
42 | -keep public class com.litesuits.http.concurrent.* { *; }
43 | -keep public class com.litesuits.http.data.* { *; }
44 | -keep public class com.litesuits.http.listener.* { *; }
45 | -keep public class com.litesuits.http.log.* { *; }
46 | -keep public class com.litesuits.http.parser.* { *; }
47 | -keep public class com.litesuits.http.exception.** { *; }
48 | -keep public class com.litesuits.http.request.** { *; }
49 | # LiteHttp Http状态用了反射,不可混淆。
50 | -keep class com.litesuits.http.data.HttpStatus { *; }
51 | # http参数不可混淆
52 | -keep public class * implements com.litesuits.http.request.param.HttpParamModel { *; }
53 |
54 | # 枚举须保住 see http://proguard.sourceforge.net/manual/examples.html#enumerations
55 | -keepclassmembers enum * {
56 | **[] $VALUES;
57 | public *;
58 | }
59 |
60 | ##---------------Begin: proguard configuration for Gson ----------
61 | # Gson uses generic type information stored in a class file when working with fields. Proguard
62 | # removes such information by default, so configure it to keep all of it.
63 | -keep class com.google.gson.** { *; }
64 | # Gson specific classes
65 | -keep class sun.misc.Unsafe { *; }
66 | -keep class com.google.gson.stream.** { *; }
67 | # Application classes that will be serialized/deserialized over Gson
68 | -keep class com.google.gson.examples.android.model.** { *; }
69 | ##---------------End: proguard configuration for Gson ----------
70 |
71 | # HTTP混淆建议:
72 | # 1. 最好保证每一个HTTP参数类(Java Model)不被混淆
73 | # 2. 最好保证每一个HTTP响应类(Java Model)不被混淆
--------------------------------------------------------------------------------
/litehttp/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/HttpCache.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http;
2 |
3 | public class HttpCache {
4 | T data;
5 | String key;
6 | long time;
7 | long length;
8 | String charSet;
9 | }
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/HttpClient.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http;
2 |
3 | import com.litesuits.http.request.AbstractRequest;
4 | import com.litesuits.http.response.InternalResponse;
5 |
6 | /**
7 | * @author 氢一 @http://def.so
8 | * @date 2016-04-04
9 | */
10 | public interface HttpClient {
11 | public void config(HttpConfig config);
12 | public void connect(AbstractRequest request, InternalResponse response) throws Exception;
13 | }
14 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/annotation/HttpBaseUrl.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author MaTianyu
10 | * @date 2015-04-26
11 | */
12 | @Target(ElementType.TYPE)
13 | @Retention(RetentionPolicy.RUNTIME)
14 | public @interface HttpBaseUrl {
15 | String value();
16 | }
17 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/annotation/HttpCacheExpire.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 | import java.util.concurrent.TimeUnit;
8 |
9 | /**
10 | * @author MaTianyu
11 | * @date 2015-04-26
12 | */
13 | @Target(ElementType.TYPE)
14 | @Retention(RetentionPolicy.RUNTIME)
15 | public @interface HttpCacheExpire {
16 | long value();
17 |
18 | TimeUnit unit();
19 | }
20 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/annotation/HttpCacheKey.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author MaTianyu
10 | * @date 2015-04-26
11 | */
12 | @Target(ElementType.TYPE)
13 | @Retention(RetentionPolicy.RUNTIME)
14 | public @interface HttpCacheKey {
15 | String value();
16 | }
17 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/annotation/HttpCacheMode.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.annotation;
2 |
3 | import com.litesuits.http.request.param.CacheMode;
4 |
5 | import java.lang.annotation.ElementType;
6 | import java.lang.annotation.Retention;
7 | import java.lang.annotation.RetentionPolicy;
8 | import java.lang.annotation.Target;
9 |
10 | /**
11 | * @author MaTianyu
12 | * @date 2015-04-26
13 | */
14 | @Target(ElementType.TYPE)
15 | @Retention(RetentionPolicy.RUNTIME)
16 | public @interface HttpCacheMode {
17 | CacheMode value();
18 | }
19 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/annotation/HttpCharSet.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author MaTianyu
10 | * @date 2015-04-26
11 | */
12 | @Target(ElementType.TYPE)
13 | @Retention(RetentionPolicy.RUNTIME)
14 | public @interface HttpCharSet {
15 | String value();
16 | }
17 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/annotation/HttpID.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author MaTianyu
10 | * @date 2015-04-26
11 | */
12 | @Target(ElementType.TYPE)
13 | @Retention(RetentionPolicy.RUNTIME)
14 | public @interface HttpID {
15 | long value();
16 | }
17 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/annotation/HttpMaxRedirect.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author MaTianyu
10 | * @date 2015-04-26
11 | */
12 | @Target(ElementType.TYPE)
13 | @Retention(RetentionPolicy.RUNTIME)
14 | public @interface HttpMaxRedirect {
15 | int value();
16 | }
17 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/annotation/HttpMaxRetry.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author MaTianyu
10 | * @date 2015-04-26
11 | */
12 | @Target(ElementType.TYPE)
13 | @Retention(RetentionPolicy.RUNTIME)
14 | public @interface HttpMaxRetry {
15 | int value();
16 | }
17 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/annotation/HttpMethod.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.annotation;
2 |
3 | import com.litesuits.http.request.param.HttpMethods;
4 |
5 | import java.lang.annotation.ElementType;
6 | import java.lang.annotation.Retention;
7 | import java.lang.annotation.RetentionPolicy;
8 | import java.lang.annotation.Target;
9 |
10 | /**
11 | * @author MaTianyu
12 | * @date 2015-04-26
13 | */
14 | @Target(ElementType.TYPE)
15 | @Retention(RetentionPolicy.RUNTIME)
16 | public @interface HttpMethod {
17 | HttpMethods value();
18 | }
19 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/annotation/HttpTag.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author MaTianyu
10 | * @date 2015-04-26
11 | */
12 | @Target(ElementType.TYPE)
13 | @Retention(RetentionPolicy.RUNTIME)
14 | public @interface HttpTag {
15 | String value();
16 | }
17 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/annotation/HttpUri.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author MaTianyu
10 | * @date 2015-04-26
11 | */
12 | @Target(ElementType.TYPE)
13 | @Retention(RetentionPolicy.RUNTIME)
14 | public @interface HttpUri {
15 | String value();
16 | }
17 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/data/Charsets.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.data;
2 |
3 | import java.nio.charset.Charset;
4 |
5 | /**
6 | * useful charsets
7 | *
8 | * @author MaTianyu
9 | * 2014-1-19上午1:21:18
10 | */
11 | public class Charsets {
12 | public static final String ASCII = "ASCII";
13 | public static final String US_ASCII = "US-ASCII";
14 |
15 | public static final String ISO_8859_1 = "ISO-8859-1";
16 |
17 | public static final String Unicode = "Unicode";
18 |
19 | public static final String BIG5 = "BIG5";
20 |
21 | public static final String UTF_8 = "UTF-8";
22 | public static final String UTF_16 = "UTF-16";
23 |
24 | public static final String GB2312 = "GB2312";
25 | public static final String GBK = "GBK";
26 | public static final String GB18030 = "GB18030";
27 |
28 | public static Charset getCharset(String charsetName){
29 | return Charset.forName(charsetName);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/data/Consts.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.data;
2 |
3 | /**
4 | * @author MaTianyu
5 | * @date 14-7-29
6 | */
7 | public class Consts {
8 | public static final String CHUNK_CODING = "chunked";
9 | public static final String IDENTITY_CODING = "identity";
10 | public static final String UTF_8 = "UTF-8";
11 | public static final String UTF_16 = "UTF-16";
12 | public static final String US_ASCII = "US-ASCII";
13 | public static final String ASCII = "ASCII";
14 | public static final String ISO_8859_1 = "ISO-8859-1";
15 | public static final String DEFAULT_CONTENT_CHARSET = "ISO-8859-1";
16 | public static final String DEFAULT_PROTOCOL_CHARSET = "US-ASCII";
17 |
18 | public static final String SCHEME_HTTP = "http";
19 | public static final String SCHEME_HTTPS = "https";
20 | public static final String CODE_CHARSET = UTF_8;
21 | public static final String EQUALS = "=";
22 | public static final String AND = "&";
23 | public static final String NONE_SPLIT = "";
24 | public static final String ONE_LEVEL_SPLIT = AND;
25 | public static final String SECOND_LEVEL_SPLIT = ",";
26 | public static final String ARRAY_ECLOSING_LEFT = "[";
27 | public static final String ARRAY_ECLOSING_RIGHT = "]";
28 | public static final String KV_ECLOSING_LEFT = "{";
29 | public static final String KV_ECLOSING_RIGHT = "}";
30 |
31 | public static final String HEADER_ACCEPT_ENCODING = "Accept-Encoding";
32 | public static final String ENCODING_GZIP = "gzip";
33 | public static final String REDIRECT_LOCATION = "Location";
34 |
35 | public static final String TRANSFER_ENCODING = "Transfer-Encoding";
36 | public static final String CONTENT_LEN = "Content-Length";
37 | public static final String CONTENT_TYPE = "Content-Type";
38 | public static final String CONTENT_ENCODING = "Content-Encoding";
39 | public static final String EXPECT_DIRECTIVE = "Expect";
40 | public static final String CONN_DIRECTIVE = "Connection";
41 | public static final String TARGET_HOST = "Host";
42 | public static final String USER_AGENT = "User-Agent";
43 | public static final String DATE_HEADER = "Date";
44 | public static final String SERVER_HEADER = "Server";
45 |
46 | public static final String EXPECT_CONTINUE = "100-Continue";
47 | public static final String CONN_CLOSE = "Close";
48 | public static final String CONN_KEEP_ALIVE = "Keep-Alive";
49 |
50 | public static final String DEFAULT_CHARSET = Charsets.UTF_8;
51 | public final static String CHARSET_PARAM = "; charset=";
52 | public final static String BOUNDARY_PARAM = "; boundary=";
53 | public static final String MIME_TYPE_TEXT = "text/plain";
54 | public static final String MIME_TYPE_JSON = "application/json";
55 | public static final String MIME_TYPE_OCTET_STREAM = "application/octet-stream";
56 | public static final String MIME_TYPE_FORM_URLENCODE = "application/x-www-form-urlencoded";
57 | public static final String MIME_TYPE_FORM_DATA = "multipart/form-data";
58 |
59 | public static final String DEFAULT_CONTENT_TYPE = MIME_TYPE_TEXT + CHARSET_PARAM + DEFAULT_CHARSET;
60 | }
61 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/data/FastJson.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.data;
2 |
3 | import com.alibaba.fastjson.JSON;
4 |
5 | import java.lang.reflect.Type;
6 |
7 | public class FastJson extends Json {
8 | private static final String TAG = FastJson.class.getSimpleName();
9 |
10 | @Override
11 | public String toJson(Object src) {
12 | return JSON.toJSONString(src);
13 | }
14 |
15 | @Override
16 | public T toObject(String json, Class claxx) {
17 | return JSON.parseObject(json, claxx);
18 | }
19 |
20 | @Override
21 | public T toObject(String s, Type type) {
22 | return JSON.parseObject(s, type);
23 | }
24 |
25 | @Override
26 | public T toObject(byte[] bytes, Class claxx) {
27 | return JSON.parseObject(bytes, claxx);
28 | }
29 | }
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/data/GsonImpl.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.data;
2 |
3 | import com.google.gson.Gson;
4 |
5 | import java.lang.reflect.Type;
6 |
7 | /**
8 | * google gson
9 | *
10 | * @author MaTianyu
11 | * 2014-2-26下午11:13:39
12 | */
13 | public class GsonImpl extends Json {
14 | private Gson gson = new Gson();
15 |
16 | @Override
17 | public String toJson(Object src) {
18 | return gson.toJson(src);
19 | }
20 |
21 | @Override
22 | public T toObject(String json, Class claxx) {
23 | return gson.fromJson(json, claxx);
24 | }
25 |
26 | @Override
27 | public T toObject(String json, Type type) {
28 | return gson.fromJson(json, type);
29 | }
30 |
31 | @Override
32 | public T toObject(byte[] bytes, Class claxx) {
33 | return gson.fromJson(new String(bytes), claxx);
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/data/Json.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.data;
2 |
3 | import java.lang.reflect.Type;
4 |
5 | /**
6 | * with this, we can change json handler easily.
7 | * alibaba fastjson can not handle private attribute that without getter method.
8 | * so we choice the google gson.
9 | *
10 | * @author MaTianyu
11 | * 2014-1-14下午11:32:32
12 | */
13 | public abstract class Json {
14 | private static Json json;
15 |
16 | /**
17 | * set new json instance
18 | *
19 | * @param json new instance
20 | * @return new instance
21 | */
22 | public static Json set(Json json) {
23 | Json.json = json;
24 | return Json.json;
25 | }
26 |
27 | /**
28 | * set default json handler: Google Gson
29 | */
30 | public static Json setDefault() {
31 | Json.json = new GsonImpl();
32 | return Json.json;
33 | }
34 |
35 | /**
36 | * get default json handler
37 | *
38 | * @return Json
39 | */
40 | public static Json get() {
41 | if (json == null) {
42 | //json = new FastJson();
43 | json = new GsonImpl();
44 | }
45 | return json;
46 | }
47 |
48 | public abstract String toJson(Object src);
49 |
50 | public abstract T toObject(String json, Class claxx);
51 |
52 | public abstract T toObject(String json, Type claxx);
53 |
54 | public abstract T toObject(byte[] bytes, Class claxx);
55 | }
56 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/data/NameValuePair.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.data;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * kv pair
7 | *
8 | * @author MaTianyu
9 | * 2014-1-18上午3:19:12
10 | */
11 | public class NameValuePair implements Serializable {
12 | private static final long serialVersionUID = -1339856642868580559L;
13 | private final String name;
14 | private final String value;
15 |
16 | public NameValuePair(String name, String value) {
17 | this.name = name;
18 | this.value = value;
19 | }
20 |
21 | public String getName() {
22 | return this.name;
23 | }
24 |
25 | public String getValue() {
26 | return this.value;
27 | }
28 |
29 | @Override
30 | public String toString() {
31 | return String.format("%-20s", this.name) + "= " + this.value;
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/data/StatisticsInfo.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.data;
2 |
3 | import java.util.concurrent.atomic.AtomicLong;
4 |
5 | public class StatisticsInfo {
6 | private AtomicLong connectTime = new AtomicLong();
7 | private AtomicLong dataLength = new AtomicLong();
8 |
9 | public void addConnectTime(long time) {
10 | connectTime.addAndGet(time);
11 | }
12 |
13 | public void addDataLength(long len) {
14 | dataLength.addAndGet(len);
15 | }
16 |
17 | public long getConnectTime() {
18 | return connectTime.longValue();
19 | }
20 |
21 | public long getDataLength() {
22 | return dataLength.longValue();
23 | }
24 |
25 | @Override
26 | public String toString() {
27 | return "StatisticsInfo{" +
28 | "connectTime=" + connectTime +
29 | ", dataLength=" + dataLength +
30 | '}';
31 | }
32 | }
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/exception/ClientException.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.exception;
2 |
3 | public enum ClientException {
4 | UrlIsNull("Url is Null!", "Url 为空!"),
5 | IllegalScheme("illegal scheme!", "非法的Scheme"),
6 | ContextNeeded("(Detect or Disable Network, etc) Need Context.", "(探测和禁用网络等)需要 Context"),
7 | PermissionDenied("Missing NETWORK-ACCESS Permission in Manifest?", "未获取访问网络或SD卡权限"),
8 | SomeOtherException("Client Exception", "客户端发生异常");
9 |
10 | private static final String TAG = ClientException.class.getName();
11 | public String reason;
12 | public String chiReason;
13 |
14 | ClientException(String name, String chiName) {
15 | this.reason = name;
16 | this.chiReason = chiName;
17 | }
18 |
19 | @Override
20 | public String toString() {
21 | return TAG + ": " + this.reason + " (" + this.chiReason + ")";
22 | }
23 | }
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/exception/HttpClientException.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.exception;
2 |
3 | /**
4 | * exception with bad request.
5 | *
6 | * Start--1(build request)-->Reqeust--2(connect network)-->Response--3(handle response)-->End
7 | *
8 | * @author MaTianyu
9 | * 2014-1-2上午12:53:13
10 | */
11 | public class HttpClientException extends HttpException {
12 | private static final long serialVersionUID = -1710690396078830713L;
13 | private ClientException exceptionType;
14 |
15 | public HttpClientException(ClientException clientExp) {
16 | super(clientExp.toString());
17 | exceptionType = clientExp;
18 | }
19 |
20 | public HttpClientException(Throwable cause) {
21 | super(cause.toString(), cause);
22 | exceptionType = ClientException.SomeOtherException;
23 | }
24 |
25 | public HttpClientException(Throwable cause, ClientException type) {
26 | super(cause.toString(), cause);
27 | exceptionType = type;
28 | }
29 |
30 | public ClientException getExceptionType() {
31 | return exceptionType;
32 | }
33 |
34 | public void setExceptionType(ClientException exceptionType) {
35 | this.exceptionType = exceptionType;
36 | }
37 |
38 | @Override
39 | public String toString() {
40 | return exceptionType.toString();
41 | }
42 |
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/exception/HttpException.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.exception;
2 |
3 | /**
4 | * Base HttpException
5 | * Start--1(build request)-->Reqeust--2(connect network)-->Response--3(handle response)-->End
6 | *
7 | * @author MaTianyu
8 | * 2014-1-2上午12:51:38
9 | */
10 | public abstract class HttpException extends Exception {
11 | private static final long serialVersionUID = -8585446012573642784L;
12 | public static boolean printStackTrace = true;
13 | protected boolean handled = true;
14 |
15 | public boolean isHandled() {
16 | return handled;
17 | }
18 |
19 | public T setHandled(boolean handled) {
20 | this.handled = handled;
21 | return (T) this;
22 | }
23 |
24 | public HttpException() {}
25 |
26 | public HttpException(String name) {
27 | super(name);
28 | }
29 |
30 | public HttpException(String name, Throwable cause) {
31 | super(name, cause);
32 | }
33 |
34 | public HttpException(Throwable cause) {
35 | super(cause);
36 | }
37 |
38 | @Override
39 | public String toString() {
40 | return "HttpException{" +
41 | "handled=" + handled +
42 | "} " + super.toString();
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/exception/HttpNetException.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.exception;
2 |
3 | /**
4 | * exception when network error happened.
5 | *
6 | * @author MaTianyu
7 | * 2014-1-2上午12:53:13
8 | */
9 | public class HttpNetException extends HttpException {
10 | private static final long serialVersionUID = 4961807092977094093L;
11 | private NetException exceptionType;
12 | //Network is unreachable
13 | public HttpNetException(NetException netExp) {
14 | super(netExp.toString());
15 | exceptionType = netExp;
16 | }
17 |
18 | /**
19 | * 包括其他异常,网络不稳定因素或者防火墙限制
20 | *
21 | * @param cause
22 | */
23 | public HttpNetException(Throwable cause) {
24 | super(cause.toString(), cause);
25 | exceptionType = NetException.NetworkUnstable;
26 | }
27 |
28 | public NetException getExceptionType() {
29 | return exceptionType;
30 | }
31 |
32 | public void setExceptionType(NetException exceptionType) {
33 | this.exceptionType = exceptionType;
34 | }
35 |
36 |
37 |
38 | @Override
39 | public String toString() {
40 | return exceptionType.toString();
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/exception/HttpServerException.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.exception;
2 |
3 | import com.litesuits.http.data.HttpStatus;
4 |
5 | /**
6 | * exception that happen in server.
7 | *
8 | * @author MaTianyu
9 | * 2014-1-2上午12:53:13
10 | */
11 | public class HttpServerException extends HttpException {
12 | private static final long serialVersionUID = 3695887939006497385L;
13 | private ServerException exceptionType;
14 | private HttpStatus status;
15 |
16 | public HttpServerException(ServerException e) {
17 | super(e.toString());
18 | exceptionType = e;
19 | }
20 |
21 | public HttpServerException(HttpStatus status) {
22 | super(status.toString());
23 | this.status = status;
24 | if (status.getCode() >= 500) {
25 | exceptionType = ServerException.ServerInnerError;
26 | } else {
27 | exceptionType = ServerException.ServerRejectClient;
28 | }
29 | }
30 |
31 | public ServerException getExceptionType() {
32 | return exceptionType;
33 | }
34 |
35 | public void setExceptionType(ServerException exceptionType) {
36 | this.exceptionType = exceptionType;
37 | }
38 |
39 | public HttpStatus getHttpStatus() {
40 | return status;
41 | }
42 |
43 | @Override
44 | public String toString() {
45 | return exceptionType + ", " + status;
46 | }
47 |
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/exception/NetException.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.exception;
2 |
3 | public enum NetException {
4 | NetworkNotAvilable("Network Is Not Avilable", "未连接网络"),
5 | NetworkUnstable("Network Is Unstable", "网络不稳定"),
6 | NetworkDisabled("Current Network Is Disabled By Your Setting", "已禁用该网络类型"),
7 | NetworkUnreachable("Network is unreachable", "网络无法访问");
8 |
9 | private static final String TAG = NetException.class.getName();
10 | public String reason;
11 | public String chiReason;
12 |
13 | NetException(String name, String chiName) {
14 | this.reason = name;
15 | this.chiReason = chiName;
16 | }
17 |
18 | @Override
19 | public String toString() {
20 | return TAG + ": " + this.reason + " (" + this.chiReason + ")";
21 | }
22 | }
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/exception/ServerException.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.exception;
2 |
3 | public enum ServerException {
4 | //500 error
5 | ServerInnerError("Server Inner Exception", "服务器内部异常"),
6 | //400 error
7 | ServerRejectClient("Server Reject Client Exception", "服务器拒绝或无法提供服务"),
8 | //redirect too many
9 | RedirectTooMuch("Server RedirectTooMuch", "重定向次数过多");
10 |
11 | private static final String TAG = ServerException.class.getName();
12 | public String reason;
13 | public String chiReason;
14 |
15 | ServerException(String name, String chiName) {
16 | this.reason = name;
17 | this.chiReason = chiName;
18 | }
19 |
20 | @Override
21 | public String toString() {
22 | return TAG +": " + this.reason + " (" + this.chiReason + ")";
23 | }
24 | }
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/exception/handler/HttpExceptionHandler.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.exception.handler;
2 |
3 | import com.litesuits.http.data.HttpStatus;
4 | import com.litesuits.http.exception.*;
5 |
6 | /**
7 | * Handle Response on UI Thread
8 | *
9 | * @author MaTianyu
10 | * 2014-2-26下午9:02:09
11 | */
12 | public abstract class HttpExceptionHandler {
13 |
14 | public HttpExceptionHandler handleException(HttpException e) {
15 | if (e != null) {
16 | if (e instanceof HttpClientException) {
17 | HttpClientException ce = ((HttpClientException) e);
18 | onClientException(ce, ce.getExceptionType());
19 | } else if (e instanceof HttpNetException) {
20 | HttpNetException ne = ((HttpNetException) e);
21 | onNetException(ne, ne.getExceptionType());
22 | } else if (e instanceof HttpServerException) {
23 | HttpServerException se = ((HttpServerException) e);
24 | onServerException(se, se.getExceptionType(), se.getHttpStatus());
25 | } else {
26 | HttpClientException ce = new HttpClientException(e);
27 | onClientException(ce, ce.getExceptionType());
28 | }
29 | e.setHandled(true);
30 | }
31 | return this;
32 | }
33 |
34 | /**
35 | * 比如 URL为空,构建参数异常以及请求过程中遇到的其他客户端异常。
36 | *
37 | * @param e
38 | */
39 | protected abstract void onClientException(HttpClientException e, ClientException type);
40 |
41 | /**
42 | * 比如 无网络,网络不稳定,该网络类型已被禁用等。
43 | *
44 | * @param e
45 | */
46 | protected abstract void onNetException(HttpNetException e, NetException type);
47 |
48 | /**
49 | * 这个时候,连接是成功的。http header已经返回,但是status code是400~599之间。
50 | * [400-499]:因为客户端原因,服务器拒绝服务
51 | * [500~599]:基本是服务器内部错误或者网关异常造成的
52 | *
53 | * @param e
54 | */
55 | protected abstract void onServerException(HttpServerException e, ServerException type, HttpStatus status);
56 | }
57 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/impl/huc/RetryHandler.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.impl.huc;
2 |
3 | import android.content.Context;
4 | import com.litesuits.http.exception.HttpNetException;
5 | import com.litesuits.http.exception.NetException;
6 | import com.litesuits.http.log.HttpLog;
7 | import com.litesuits.http.network.Network;
8 |
9 | import javax.net.ssl.SSLException;
10 | import java.io.FileNotFoundException;
11 | import java.io.IOException;
12 | import java.net.*;
13 | import java.util.HashSet;
14 |
15 | /**
16 | * determine whether to send request try again.
17 | * 试验发现,当url非法时,{@link HttpURLConnection}报MalformedURLException异常,
18 | * 而apache httpclient会报IllegalStateException异常。
19 | * 当url非法,和ssl错误时,不用重试。 当有可用网络但连接不稳定时,一般会报IO异常,此种情况尝试重试,以提高成功率。
20 | * 继承StandardHttpRequestRetryHandler因用到其判断请求方式是否幂等和连接是否取消等方法。
21 | *
22 | * @author MaTianyu
23 | * 2014-1-1下午5:03:46
24 | */
25 | public class RetryHandler {
26 | public static final String TAG = RetryHandler.class.getSimpleName();
27 | private HashSet> whitelist = new HashSet>();
28 | private HashSet> blacklist = new HashSet>();
29 |
30 | private int retrySleepTimeMS;
31 |
32 | /**
33 | * @param retrySleepTimeMS if the network is unstable, wait retrySleepTimeMS then start retry.
34 | */
35 | public RetryHandler(int retrySleepTimeMS) {
36 | this.retrySleepTimeMS = retrySleepTimeMS;
37 | whitelist.add(SocketException.class);
38 | whitelist.add(SocketTimeoutException.class);
39 |
40 | blacklist.add(MalformedURLException.class);
41 | blacklist.add(UnknownHostException.class);
42 | blacklist.add(FileNotFoundException.class);
43 | blacklist.add(SSLException.class);
44 | }
45 |
46 | public RetryHandler setRetrySleepTimeMS(int retrySleepTimeMS) {
47 | this.retrySleepTimeMS = retrySleepTimeMS;
48 | return this;
49 | }
50 |
51 | public boolean retryRequest(IOException exception, int retryCount, int maxRetries,
52 | Context appContext) throws HttpNetException, InterruptedException {
53 | boolean retry = true;
54 | if (retryCount > maxRetries) {
55 | if (HttpLog.isPrint) {
56 | HttpLog.w(TAG, "retry count > max retry times..");
57 | }
58 | throw new HttpNetException(exception);
59 | } else if (isInList(blacklist, exception)) {
60 | if (HttpLog.isPrint) {
61 | HttpLog.w(TAG, "exception in blacklist..");
62 | }
63 | retry = false;
64 | } else if (isInList(whitelist, exception)) {
65 | if (HttpLog.isPrint) {
66 | HttpLog.w(TAG, "exception in whitelist..");
67 | }
68 | retry = true;
69 | }
70 | if (retry) {
71 | if (appContext != null) {
72 | if (Network.isConnected(appContext)) {
73 | HttpLog.d(TAG, "Network isConnected, retry now");
74 | } else if (Network.isConnectedOrConnecting(appContext)) {
75 | if (HttpLog.isPrint) {
76 | HttpLog.v(TAG, "Network is Connected Or Connecting, wait for retey : "
77 | + retrySleepTimeMS + " ms");
78 | }
79 | Thread.sleep(retrySleepTimeMS);
80 | } else {
81 | HttpLog.d(TAG, "Without any Network , immediately cancel retry");
82 | throw new HttpNetException(NetException.NetworkNotAvilable);
83 | }
84 | } else {
85 | if (HttpLog.isPrint) {
86 | HttpLog.v(TAG, "app context is null..");
87 | HttpLog.v(TAG, "wait for retry : " + retrySleepTimeMS + " ms");
88 | }
89 | Thread.sleep(retrySleepTimeMS);
90 | }
91 | }
92 | if (HttpLog.isPrint) {
93 | HttpLog.i(TAG, "retry: " + retry + " , retryCount: " + retryCount + " , exception: " + exception);
94 | }
95 | return retry;
96 | }
97 |
98 | protected boolean isInList(HashSet> list, Throwable error) {
99 | for (Class> aList : list) {
100 | if (aList.isInstance(error)) {
101 | return true;
102 | }
103 | }
104 | return false;
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/listener/StatisticsListener.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.listener;
2 |
3 | import android.os.SystemClock;
4 | import com.litesuits.http.data.StatisticsInfo;
5 | import com.litesuits.http.request.AbstractRequest;
6 | import com.litesuits.http.response.InternalResponse;
7 | import com.litesuits.http.response.Response;
8 |
9 | public class StatisticsListener {
10 | private static final String TAG = StatisticsListener.class.getSimpleName();
11 | private StatisticsInfo statisticsInfo;
12 | private InternalResponse internalResponse;
13 | private long total, connect, connectStart, read, readStart, headLen, readLen;
14 |
15 | public StatisticsListener(InternalResponse internalResponse, StatisticsInfo statisticsInfo) {
16 | this.internalResponse = internalResponse;
17 | this.statisticsInfo = statisticsInfo;
18 | }
19 |
20 | public void onStart(AbstractRequest request) {
21 | total = SystemClock.uptimeMillis();
22 | }
23 |
24 | public void onEnd(Response res) {
25 | if (total > 0) {
26 | total = SystemClock.uptimeMillis() - total;
27 | internalResponse.setUseTime(total);
28 | statisticsInfo.addConnectTime(total);
29 |
30 | headLen = internalResponse.getContentLength();
31 | readLen = internalResponse.getReadedLength();
32 | long len = 0;
33 | if (readLen > 0) {
34 | len = readLen;
35 | }
36 | if (len == 0 && headLen > 0) {
37 | len = headLen;
38 | }
39 | statisticsInfo.addDataLength(len);
40 | }
41 | }
42 |
43 | public void onRetry(AbstractRequest req, int max, int now) {
44 |
45 | }
46 |
47 | public void onRedirect(AbstractRequest req) {
48 |
49 | }
50 |
51 | public void onPreConnect(AbstractRequest request) {
52 | connectStart = SystemClock.uptimeMillis();
53 | }
54 |
55 | public void onAfterConnect(AbstractRequest request) {
56 | connect += SystemClock.uptimeMillis() - connectStart;
57 | }
58 |
59 | public void onPreRead(AbstractRequest request) {
60 | readStart = SystemClock.uptimeMillis();
61 | }
62 |
63 | public void onAfterRead(AbstractRequest request) {
64 | read += SystemClock.uptimeMillis() - readStart;
65 | }
66 |
67 | @Override
68 | public String toString() {
69 | return resToString();
70 | }
71 |
72 | public String resToString() {
73 | return
74 | "\n[length] headerLen: " + headLen
75 | + " B, readedLen: " + readLen + " B, global total len: "
76 | + statisticsInfo.getDataLength() + " B"
77 | + "\n[time] connect : " + connect + " MS, read: "
78 | + read + " MS, total: " + total + " MS, global total time: "
79 | + statisticsInfo.getConnectTime() + " MS";
80 | }
81 | }
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/parser/DataParser.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.parser;
2 |
3 | import com.litesuits.http.HttpConfig;
4 | import com.litesuits.http.data.Consts;
5 | import com.litesuits.http.listener.HttpListener;
6 | import com.litesuits.http.request.AbstractRequest;
7 |
8 | import java.io.File;
9 | import java.io.IOException;
10 | import java.io.InputStream;
11 |
12 | /**
13 | * base data parser
14 | *
15 | * @author MaTianyu
16 | * 2014-2-21下午7:26:58
17 | */
18 | public abstract class DataParser {
19 | protected static final String TAG = DataParser.class.getSimpleName();
20 | protected T data;
21 | protected long readLength;
22 | protected AbstractRequest request;
23 | protected String charSet = Consts.DEFAULT_CHARSET;
24 | protected int buffSize = HttpConfig.DEFAULT_BUFFER_SIZE;
25 |
26 | /**
27 | * source 1. read data form network
28 | */
29 | public T readFromNetStream(InputStream stream, long len, String charSet) throws IOException {
30 | if (stream != null) {
31 | try {
32 | this.data = parseNetStream(stream, len, charSet);
33 | } finally {
34 | stream.close();
35 | }
36 | }
37 | return this.data;
38 | }
39 |
40 | /**
41 | * source 2. read data form disk
42 | */
43 | public abstract T readFromDiskCache(File file) throws IOException;
44 |
45 |
46 | /**
47 | * source 3. read data form network
48 | */
49 | public final T readFromMemoryCache(T data) {
50 | if (isMemCacheSupport()) {
51 | this.data = data;
52 | }
53 | return this.data;
54 | }
55 |
56 | /**
57 | * parse network stream
58 | */
59 | protected abstract T parseNetStream(InputStream stream, long totalLength,
60 | String charSet) throws IOException;
61 |
62 | /**
63 | * is memory cache supported
64 | */
65 | public abstract boolean isMemCacheSupport();
66 |
67 | /**
68 | * get the data
69 | *
70 | * @return custom data
71 | */
72 | public final T getData() {
73 | return data;
74 | }
75 |
76 |
77 | /**
78 | * length of data
79 | */
80 | public final long getReadedLength() {
81 | return readLength;
82 | }
83 |
84 | /**
85 | * set a request to parser
86 | */
87 | public final void setRequest(AbstractRequest request) {
88 | this.request = request;
89 | if (request.getCharSet() != null) {
90 | charSet = request.getCharSet();
91 | }
92 | }
93 |
94 | public String getRawString() {
95 | return null;
96 | }
97 |
98 | /**
99 | * translate original bytes to custom bytes.
100 | * if your data is encrypted, you can override this method to decrypt it.
101 | *
102 | * @param bytes data form server
103 | * @return decrypt data
104 | */
105 | protected byte[] translateBytes(byte[] bytes) {
106 | return bytes;
107 | }
108 |
109 | /**
110 | * notify readed length to listener
111 | */
112 | protected final void notifyReading(long total, long len) {
113 | HttpListener listener = request.getHttpListener();
114 | if (listener != null) {
115 | listener.notifyCallLoading(request, total, len);
116 | }
117 | }
118 |
119 | @Override
120 | public String toString() {
121 | return "DataParser{" +
122 | "buffSize=" + buffSize +
123 | ", readLength=" + readLength +
124 | '}';
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/parser/FileCacheableParser.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.parser;
2 |
3 | import com.litesuits.http.log.HttpLog;
4 |
5 | import java.io.*;
6 |
7 | /**
8 | * @author MaTianyu
9 | * @date 2015-04-26
10 | */
11 | public abstract class FileCacheableParser extends DataParser {
12 | protected File file;
13 | public FileCacheableParser() {
14 | }
15 | public FileCacheableParser(File saveToFile) {
16 | this.file = saveToFile;
17 | }
18 |
19 | public final T readFromDiskCache(File file) throws IOException {
20 | data = parseDiskCache(file);
21 | return data;
22 | }
23 |
24 | /**
25 | * parse local file
26 | */
27 | protected abstract T parseDiskCache(File file) throws IOException;
28 |
29 | @Override
30 | public boolean isMemCacheSupport() {
31 | return false;
32 | }
33 |
34 | protected final File streamToFile(InputStream is, long len) throws IOException {
35 | File file = request.getCachedFile();
36 | FileOutputStream fos = null;
37 | try {
38 | File pFile = file.getParentFile();
39 | if (!pFile.exists()) {
40 | boolean mk = pFile.mkdirs();
41 | if (HttpLog.isPrint) {
42 | HttpLog.i(TAG, "keep cache mkdirs result: " + mk + " path:" + pFile.getAbsolutePath());
43 | }
44 | }
45 | fos = new FileOutputStream(file);
46 | byte[] tmp = new byte[buffSize];
47 | int l;
48 | while (!request.isCancelledOrInterrupted() && (l = is.read(tmp)) != -1) {
49 | tmp = translateBytes(tmp);
50 | fos.write(tmp, 0, l);
51 | readLength += l;
52 | notifyReading(len, readLength);
53 | }
54 | if (HttpLog.isPrint) {
55 | HttpLog.i("FileParser", "file len: " + file.length());
56 | }
57 | } finally {
58 | if (fos != null) {
59 | fos.close();
60 | }
61 | }
62 | return file;
63 | }
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/parser/impl/BitmapParser.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.parser.impl;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.BitmapFactory;
5 | import com.litesuits.http.parser.FileCacheableParser;
6 |
7 | import java.io.File;
8 | import java.io.IOException;
9 | import java.io.InputStream;
10 |
11 | /**
12 | * parse inputstream to bitmap.
13 | *
14 | * @author MaTianyu
15 | * 2014-2-21下午8:56:59
16 | */
17 | public class BitmapParser extends FileCacheableParser {
18 | public BitmapParser() {}
19 | public BitmapParser(File file) {
20 | this.file = file;
21 | }
22 |
23 | @Override
24 | public Bitmap parseNetStream(InputStream stream, long len, String charSet) throws IOException {
25 | //if (this.file != null || request.isCachedModel()
26 | // || (request.getHttpListener() != null && request.getHttpListener().isReadingNotify())) {
27 | // File file = streamToFile(stream, len, cacheDir);
28 | // return BitmapFactory.decodeFile(file.getAbsolutePath());
29 | //} else {
30 | // return BitmapFactory.decodeStream(stream);
31 | //}
32 | file = streamToFile(stream, len);
33 | return BitmapFactory.decodeFile(file.getAbsolutePath());
34 | }
35 |
36 | @Override
37 | public Bitmap parseDiskCache(File file) {
38 | return BitmapFactory.decodeFile(file.getAbsolutePath());
39 | }
40 | }
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/parser/impl/BytesParser.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.parser.impl;
2 |
3 | import com.litesuits.http.parser.MemCacheableParser;
4 |
5 | import java.io.IOException;
6 | import java.io.InputStream;
7 |
8 | /**
9 | * parse inputstream to bytes.
10 | *
11 | * @author MaTianyu
12 | * 2014-2-21下午8:56:59
13 | */
14 | public class BytesParser extends MemCacheableParser {
15 |
16 | @Override
17 | public byte[] parseNetStream(InputStream stream, long len, String charSet) throws IOException {
18 | return streamToByteArray(stream, len);
19 | }
20 |
21 | @Override
22 | protected byte[] parseDiskCache(InputStream stream, long length) throws IOException {
23 | return streamToByteArray(stream, length);
24 | }
25 |
26 |
27 | @Override
28 | protected boolean tryKeepToCache(byte[] data) throws IOException {
29 | return keepToCache(data);
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/parser/impl/FileParser.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.parser.impl;
2 |
3 | import com.litesuits.http.parser.FileCacheableParser;
4 |
5 | import java.io.File;
6 | import java.io.IOException;
7 | import java.io.InputStream;
8 |
9 | /**
10 | * parse inputstream to file.
11 | *
12 | * @author MaTianyu
13 | * 2014-2-21下午8:56:59
14 | */
15 | public class FileParser extends FileCacheableParser {
16 | public FileParser() {
17 | }
18 | public FileParser(File saveToFile) {
19 | this.file = saveToFile;
20 | }
21 |
22 | @Override
23 | public File parseNetStream(InputStream stream, long len, String charSet) throws IOException {
24 | return streamToFile(stream, len);
25 | }
26 |
27 | @Override
28 | public File parseDiskCache(File file) {
29 | return file;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/parser/impl/JsonParser.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.parser.impl;
2 |
3 | import com.litesuits.http.data.Json;
4 | import com.litesuits.http.parser.MemCacheableParser;
5 |
6 | import java.io.IOException;
7 | import java.io.InputStream;
8 | import java.lang.reflect.Type;
9 |
10 | /**
11 | * parse inputstream to java model.
12 | *
13 | * @author MaTianyu
14 | * 2014-4-19
15 | */
16 | public class JsonParser extends MemCacheableParser {
17 | protected Type claxx;
18 | protected String json;
19 |
20 | public JsonParser(Type claxx) {
21 | this.claxx = claxx;
22 | }
23 |
24 | @Override
25 | protected T parseNetStream(InputStream stream, long totalLength
26 | , String charSet) throws IOException {
27 | json = streamToString(stream, totalLength, charSet);
28 | return Json.get().toObject(json, claxx);
29 | }
30 |
31 | @Override
32 | protected T parseDiskCache(InputStream stream, long length) throws IOException {
33 | json = streamToString(stream, length, charSet);
34 | return Json.get().toObject(json, claxx);
35 | }
36 |
37 | @Override
38 | protected boolean tryKeepToCache(T data) throws IOException {
39 | return keepToCache(json);
40 | }
41 |
42 | /**
43 | * get the row string
44 | */
45 | @Override
46 | public String getRawString() {
47 | return json;
48 | }
49 |
50 | /**
51 | * get the json model
52 | */
53 | public C getJsonModel(Class claxx) {
54 | return Json.get().toObject(json, claxx);
55 | }
56 |
57 | @Override
58 | public String toString() {
59 | return "JsonParser{" +
60 | "claxx=" + claxx +
61 | "} " + super.toString();
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/parser/impl/StringParser.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.parser.impl;
2 |
3 | import com.litesuits.http.parser.MemCacheableParser;
4 |
5 | import java.io.IOException;
6 | import java.io.InputStream;
7 |
8 | /**
9 | * parse inputstream to string.
10 | *
11 | * @author MaTianyu
12 | * 2014-2-21下午8:56:59
13 | */
14 | public class StringParser extends MemCacheableParser {
15 |
16 | @Override
17 | public String parseNetStream(InputStream stream, long len, String charSet) throws IOException {
18 | return streamToString(stream, len, charSet);
19 | }
20 |
21 | @Override
22 | protected String parseDiskCache(InputStream stream, long length) throws IOException {
23 | return streamToString(stream, length, charSet);
24 | }
25 |
26 | @Override
27 | protected boolean tryKeepToCache(String data) throws IOException {
28 | return keepToCache(data);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/request/BitmapRequest.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.request;
2 |
3 | import android.graphics.Bitmap;
4 | import com.litesuits.http.parser.DataParser;
5 | import com.litesuits.http.parser.impl.BitmapParser;
6 | import com.litesuits.http.request.param.HttpParamModel;
7 | import com.litesuits.http.request.param.NonHttpParam;
8 |
9 | import java.io.File;
10 |
11 | /**
12 | * @author MaTianyu
13 | * @date 2015-04-18
14 | */
15 | public class BitmapRequest extends AbstractRequest {
16 |
17 | @NonHttpParam
18 | protected File saveToFile;
19 |
20 | public BitmapRequest(HttpParamModel model) {
21 | super(model);
22 | }
23 |
24 | public BitmapRequest(HttpParamModel model, File saveToFile) {
25 | super(model);
26 | this.saveToFile = saveToFile;
27 | }
28 |
29 | public BitmapRequest(HttpParamModel model, String saveToPath) {
30 | super(model);
31 | setFileSavePath(saveToPath);
32 | }
33 |
34 | public BitmapRequest(String url) {
35 | super(url);
36 | }
37 |
38 | public BitmapRequest(String url, File saveToFile) {
39 | super(url);
40 | this.saveToFile = saveToFile;
41 | }
42 |
43 | public BitmapRequest(String url, String saveToPath) {
44 | super(url);
45 | setFileSavePath(saveToPath);
46 | }
47 |
48 |
49 | public BitmapRequest setFileSavePath(String savaToPath) {
50 | if (savaToPath != null) {
51 | saveToFile = new File(savaToPath);
52 | }
53 | return this;
54 | }
55 |
56 | public File getCachedFile() {
57 | return saveToFile != null ? saveToFile : super.getCachedFile();
58 | }
59 |
60 | @Override
61 | public DataParser createDataParser() {
62 | return new BitmapParser(saveToFile);
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/request/BytesRequest.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.request;
2 |
3 | import com.litesuits.http.parser.DataParser;
4 | import com.litesuits.http.parser.impl.BytesParser;
5 | import com.litesuits.http.request.param.HttpParamModel;
6 |
7 | /**
8 | * @author MaTianyu
9 | * @date 2015-04-18
10 | */
11 | public class BytesRequest extends AbstractRequest {
12 |
13 | public BytesRequest(String url) {
14 | super(url);
15 | }
16 |
17 | public BytesRequest(HttpParamModel model) {
18 | super(model);
19 | }
20 |
21 | @Override
22 | public DataParser createDataParser() {
23 | return new BytesParser();
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/request/FileRequest.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.request;
2 |
3 | import com.litesuits.http.parser.DataParser;
4 | import com.litesuits.http.parser.impl.FileParser;
5 | import com.litesuits.http.request.param.HttpParamModel;
6 | import com.litesuits.http.request.param.NonHttpParam;
7 |
8 | import java.io.File;
9 |
10 | /**
11 | * @author MaTianyu
12 | * @date 2015-04-18
13 | */
14 | public class FileRequest extends AbstractRequest {
15 |
16 | @NonHttpParam
17 | private File saveToFile;
18 |
19 | public FileRequest(String url) {
20 | super(url);
21 | }
22 |
23 | public FileRequest(HttpParamModel model, String savaToPath) {
24 | super(model);
25 | setFileSavePath(savaToPath);
26 | }
27 |
28 | public FileRequest(HttpParamModel model, File saveToFile) {
29 | super(model);
30 | this.saveToFile = saveToFile;
31 | }
32 |
33 | public FileRequest(String url, File saveToFile) {
34 | super(url);
35 | this.saveToFile = saveToFile;
36 | }
37 |
38 | public FileRequest(String url, String savaToPath) {
39 | super(url);
40 | setFileSavePath(savaToPath);
41 | }
42 |
43 | public FileRequest setFileSavePath(String savaToPath) {
44 | if (savaToPath != null) {
45 | saveToFile = new File(savaToPath);
46 | }
47 | return this;
48 | }
49 |
50 | public File getCachedFile() {
51 | return saveToFile != null ? saveToFile : super.getCachedFile();
52 | }
53 |
54 | @Override
55 | public DataParser createDataParser() {
56 | return new FileParser(saveToFile);
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/request/JsonAbsRequest.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.request;
2 |
3 | import com.litesuits.http.parser.DataParser;
4 | import com.litesuits.http.parser.impl.JsonParser;
5 | import com.litesuits.http.request.param.HttpParamModel;
6 | import com.litesuits.http.request.param.NonHttpParam;
7 |
8 | import java.lang.reflect.ParameterizedType;
9 | import java.lang.reflect.Type;
10 |
11 | /**
12 | * @author MaTianyu
13 | * @date 2015-04-18
14 | */
15 | public abstract class JsonAbsRequest extends AbstractRequest {
16 |
17 | @NonHttpParam
18 | protected Type resultType;
19 |
20 | public JsonAbsRequest(String url) {
21 | super(url);
22 | }
23 |
24 | protected JsonAbsRequest(HttpParamModel model) {
25 | super(model);
26 | }
27 |
28 | protected JsonAbsRequest(String url, HttpParamModel model) {
29 | super(url, model);
30 | }
31 |
32 | @Override
33 | public DataParser createDataParser() {
34 | return new JsonParser(getResultType());
35 | }
36 |
37 | public Type getResultType() {
38 | if (resultType == null) {
39 | resultType = ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
40 | }
41 | return resultType;
42 | }
43 |
44 | @SuppressWarnings("unchecked")
45 | public R setResultType(Type resultType) {
46 | this.resultType = resultType;
47 | return (R) this;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/request/JsonRequest.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.request;
2 |
3 | import com.litesuits.http.data.TypeToken;
4 | import com.litesuits.http.parser.DataParser;
5 | import com.litesuits.http.parser.impl.JsonParser;
6 | import com.litesuits.http.request.param.HttpParamModel;
7 |
8 | import java.lang.reflect.Type;
9 |
10 | /**
11 | * @author MaTianyu
12 | * @date 2015-04-18
13 | */
14 | public class JsonRequest extends JsonAbsRequest {
15 |
16 | public JsonRequest(String url, Type resultType) {
17 | super(url);
18 | setResultType(resultType);
19 | }
20 |
21 | public JsonRequest(HttpParamModel model, Type resultType) {
22 | super(model);
23 | setResultType(resultType);
24 | }
25 |
26 | public JsonRequest(String url, TypeToken resultType) {
27 | super(url);
28 | setResultType(resultType.getType());
29 | }
30 |
31 | public JsonRequest(HttpParamModel model, TypeToken resultType) {
32 | super(model);
33 | setResultType(resultType.getType());
34 | }
35 |
36 | @Override
37 | public DataParser createDataParser() {
38 | return new JsonParser(resultType);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/request/StringRequest.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.request;
2 |
3 | import com.litesuits.http.parser.DataParser;
4 | import com.litesuits.http.parser.impl.StringParser;
5 | import com.litesuits.http.request.param.HttpParamModel;
6 |
7 | /**
8 | * @author MaTianyu
9 | * @date 2015-04-18
10 | */
11 | public class StringRequest extends AbstractRequest {
12 |
13 | public StringRequest(String url) {
14 | super(url);
15 | }
16 |
17 | public StringRequest(HttpParamModel model) {
18 | super(model);
19 | }
20 |
21 | public StringRequest(String url, HttpParamModel model) {
22 | super(url, model);
23 | }
24 |
25 | @Override
26 | public DataParser createDataParser() {
27 | return new StringParser();
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/request/content/ByteArrayBody.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.request.content;
2 |
3 | import com.litesuits.http.data.Consts;
4 |
5 | import java.io.IOException;
6 | import java.io.OutputStream;
7 | import java.util.Arrays;
8 |
9 | /**
10 | * @author MaTianyu
11 | * @date 14-7-29
12 | */
13 | public class ByteArrayBody extends HttpBody {
14 | private byte[] bytes;
15 |
16 | public ByteArrayBody(byte[] bytes) {
17 | this(bytes, Consts.MIME_TYPE_OCTET_STREAM);
18 | }
19 |
20 | public ByteArrayBody(byte[] bytes, String contentType) {
21 | this.bytes = bytes;
22 | this.contentType = contentType;
23 | }
24 |
25 |
26 | @Override
27 | public long getContentLength() {
28 | return bytes.length;
29 | }
30 |
31 | @Override
32 | public void writeTo(OutputStream outstream) throws IOException {
33 | outstream.write(bytes);
34 | outstream.flush();
35 | }
36 |
37 | public byte[] getBytes() {
38 | return bytes;
39 | }
40 |
41 | @Override
42 | public String toString() {
43 | return "ByteArrayBody{" +
44 | "bytes=" + Arrays.toString(bytes) +
45 | "} " + super.toString();
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/request/content/FileBody.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.request.content;
2 |
3 | import com.litesuits.http.data.Consts;
4 |
5 | import java.io.*;
6 |
7 | /**
8 | * @author MaTianyu
9 | * @date 14-7-29
10 | */
11 | public class FileBody extends HttpBody {
12 | private File file;
13 |
14 | public FileBody(File file) {
15 | this(file, Consts.MIME_TYPE_OCTET_STREAM);
16 | }
17 |
18 | public FileBody(File file, String contentType) {
19 | this.file = file;
20 | this.contentType = contentType;
21 | }
22 |
23 | public File getFile() {
24 | return file;
25 | }
26 |
27 | @Override
28 | public long getContentLength() {
29 | return file.length();
30 | }
31 |
32 | @Override
33 | public void writeTo(OutputStream outstream) throws IOException {
34 | final InputStream instream = new FileInputStream(this.file);
35 | try {
36 | final byte[] tmp = new byte[OUTPUT_BUFFER_SIZE];
37 | int l;
38 | while ((l = instream.read(tmp)) != -1) {
39 | outstream.write(tmp, 0, l);
40 | }
41 | outstream.flush();
42 | } finally {
43 | instream.close();
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/request/content/HttpBody.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.request.content;
2 |
3 | import com.litesuits.http.HttpConfig;
4 | import com.litesuits.http.listener.HttpListener;
5 | import com.litesuits.http.request.AbstractRequest;
6 |
7 | import java.io.IOException;
8 | import java.io.OutputStream;
9 |
10 | /**
11 | * @author MaTianyu
12 | * @date 14-7-29
13 | */
14 | public abstract class HttpBody {
15 | public static final int OUTPUT_BUFFER_SIZE = HttpConfig.DEFAULT_BUFFER_SIZE;
16 | protected HttpListener httpListener;
17 | protected AbstractRequest request;
18 | protected String contentType;
19 | protected String contentEncoding;
20 |
21 | public String getContentType() {
22 | return contentType;
23 | }
24 |
25 | public abstract long getContentLength();
26 |
27 | public abstract void writeTo(OutputStream outstream) throws IOException;
28 |
29 | public HttpBody setContentType(String contentType) {
30 | this.contentType = contentType;
31 | return this;
32 | }
33 |
34 | public String getContentEncoding() {
35 | return contentEncoding;
36 | }
37 |
38 | public HttpBody setContentEncoding(String contentEncoding) {
39 | this.contentEncoding = contentEncoding;
40 | return this;
41 | }
42 |
43 | public HttpListener getHttpListener() {
44 | return httpListener;
45 | }
46 |
47 | public void setHttpListener(HttpListener httpListener) {
48 | this.httpListener = httpListener;
49 | }
50 |
51 | public AbstractRequest getRequest() {
52 | return request;
53 | }
54 |
55 | public void setRequest(AbstractRequest request) {
56 | this.request = request;
57 | setHttpListener(request.getHttpListener());
58 | }
59 | }
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/request/content/InputStreamBody.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.request.content;
2 |
3 | import com.litesuits.http.data.Consts;
4 |
5 | import java.io.IOException;
6 | import java.io.InputStream;
7 | import java.io.OutputStream;
8 |
9 | /**
10 | * @author MaTianyu
11 | * @date 14-7-29
12 | */
13 | public class InputStreamBody extends HttpBody {
14 | protected InputStream instream;
15 | protected long length;
16 |
17 | public InputStreamBody(InputStream instream) {
18 | this(instream, null);
19 | }
20 |
21 | public InputStreamBody(InputStream instream, String contentType) {
22 | this(instream, contentType, -1);
23 | }
24 |
25 | public InputStreamBody(InputStream instream, String contentType, long length) {
26 | this.instream = instream;
27 | this.contentType = (contentType != null) ? contentType : Consts.MIME_TYPE_OCTET_STREAM;
28 | this.length = length;
29 | }
30 |
31 | public InputStream getInstream() {
32 | return instream;
33 | }
34 |
35 | @Override
36 | public long getContentLength() {
37 | return length;
38 | }
39 |
40 | @Override
41 | public void writeTo(OutputStream outstream) throws IOException {
42 | if (instream == null) {
43 | return;
44 | }
45 | try {
46 | final byte[] buffer = new byte[OUTPUT_BUFFER_SIZE];
47 | int l;
48 | if (this.length < 0) {
49 | // consume until EOF
50 | while ((l = instream.read(buffer)) != -1) {
51 | outstream.write(buffer, 0, l);
52 | }
53 | } else {
54 | // consume no more than length
55 | long remaining = this.length;
56 | while (remaining > 0) {
57 | l = instream.read(buffer, 0, (int) Math.min(OUTPUT_BUFFER_SIZE, remaining));
58 | if (l == -1) {
59 | break;
60 | }
61 | outstream.write(buffer, 0, l);
62 | remaining -= l;
63 | }
64 | }
65 | outstream.flush();
66 | } finally {
67 | instream.close();
68 | }
69 | }
70 |
71 | @Override
72 | public String toString() {
73 | return "InputStreamBody{" +
74 | "instream=" + instream +
75 | ", length=" + length +
76 | "} " + super.toString();
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/request/content/JsonBody.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.request.content;
2 |
3 | import com.litesuits.http.data.Consts;
4 | import com.litesuits.http.data.Json;
5 |
6 | /**
7 | * @author MaTianyu
8 | * @date 14-7-29
9 | */
10 | public class JsonBody extends StringBody {
11 |
12 | public JsonBody(Object param) {
13 | this(param, Consts.DEFAULT_CHARSET);
14 | }
15 |
16 | public JsonBody(String param) {
17 | this(param, Consts.DEFAULT_CHARSET);
18 | }
19 |
20 | public JsonBody(String json, String charset) {
21 | super(json, Consts.MIME_TYPE_JSON, charset);
22 | }
23 |
24 | public JsonBody(Object param, String charset) {
25 | super(Json.get().toJson(param), Consts.MIME_TYPE_JSON, charset);
26 | }
27 |
28 | @Override
29 | public String toString() {
30 | return "JsonBody{} " + super.toString();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/request/content/SerializableBody.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.request.content;
2 |
3 | import java.io.ByteArrayOutputStream;
4 | import java.io.IOException;
5 | import java.io.ObjectOutputStream;
6 | import java.io.Serializable;
7 |
8 | /**
9 | * @author MaTianyu
10 | * @date 14-7-29
11 | */
12 | public class SerializableBody extends ByteArrayBody {
13 |
14 | public SerializableBody(Serializable ser) {
15 | super(getBytes(ser), null);
16 | }
17 |
18 | public static byte[] getBytes(Serializable ser) {
19 | try {
20 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
21 | ObjectOutputStream oos = null;
22 | oos = new ObjectOutputStream(baos);
23 | oos.writeObject(ser);
24 | return baos.toByteArray();
25 | } catch (IOException e) {
26 | e.printStackTrace();
27 | }
28 | return null;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/request/content/StringBody.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.request.content;
2 |
3 | import com.litesuits.http.data.Consts;
4 |
5 | import java.io.IOException;
6 | import java.io.OutputStream;
7 | import java.io.UnsupportedEncodingException;
8 |
9 | /**
10 | * @author MaTianyu
11 | * @date 14-7-29
12 | */
13 | public class StringBody extends HttpBody {
14 | protected String charset;
15 | protected String mimeType;
16 | protected String string;
17 | protected byte[] content;
18 |
19 |
20 | public StringBody(String string) {
21 | this(string, null, null);
22 | }
23 |
24 | public StringBody(String string, String mimeType, String charset) {
25 | if (mimeType == null) {
26 | mimeType = Consts.MIME_TYPE_TEXT;
27 | }
28 | if (charset == null) {
29 | charset = Consts.DEFAULT_CHARSET;
30 | }
31 | this.charset = charset;
32 | this.string = string;
33 | this.mimeType = mimeType;
34 | try {
35 | this.content = string.getBytes(charset);
36 | } catch (UnsupportedEncodingException e) {
37 | e.printStackTrace();
38 | }
39 | this.contentType = mimeType + Consts.CHARSET_PARAM + charset;
40 | }
41 |
42 | @Override
43 | public long getContentLength() {
44 | return content.length;
45 | }
46 |
47 | @Override
48 | public void writeTo(OutputStream outstream) throws IOException {
49 | outstream.write(this.content);
50 | outstream.flush();
51 | }
52 |
53 | public String getString() {
54 | return string;
55 | }
56 |
57 | public String getCharset() {
58 | return charset;
59 | }
60 |
61 | public String getMimeType() {
62 | return mimeType;
63 | }
64 |
65 | public byte[] getContent() {
66 | return content;
67 | }
68 |
69 | @Override
70 | public String toString() {
71 | return "StringBody{" +
72 | "charset='" + charset + '\'' +
73 | ", mimeType='" + mimeType + '\'' +
74 | ", string='" + string + '\'' +
75 | "} " ;
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/request/content/UrlEncodedFormBody.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.request.content;
2 |
3 | import com.litesuits.http.data.Consts;
4 | import com.litesuits.http.data.NameValuePair;
5 |
6 | import java.io.UnsupportedEncodingException;
7 | import java.net.URLEncoder;
8 | import java.util.List;
9 | import java.util.Map;
10 |
11 | /**
12 | * @author MaTianyu
13 | * @date 14-7-29
14 | */
15 | public class UrlEncodedFormBody extends StringBody {
16 |
17 | public UrlEncodedFormBody(String encodeBody) {
18 | super(encodeBody, Consts.MIME_TYPE_FORM_URLENCODE, Consts.DEFAULT_CHARSET);
19 | }
20 |
21 | public UrlEncodedFormBody(String encodeBody, String charset) {
22 | super(encodeBody, Consts.MIME_TYPE_FORM_URLENCODE, charset);
23 | }
24 |
25 | public UrlEncodedFormBody(List list) {
26 | super(handleListValue(list, Consts.DEFAULT_CHARSET), Consts.MIME_TYPE_FORM_URLENCODE, Consts.DEFAULT_CHARSET);
27 | }
28 |
29 | public UrlEncodedFormBody(List list, String charset) {
30 | super(handleListValue(list, charset), Consts.MIME_TYPE_FORM_URLENCODE, charset);
31 | }
32 |
33 | public UrlEncodedFormBody(Map map) {
34 | super(handleMapValue(map, Consts.DEFAULT_CHARSET), Consts.MIME_TYPE_FORM_URLENCODE, Consts.DEFAULT_CHARSET);
35 | }
36 |
37 | public UrlEncodedFormBody(Map map, String charset) {
38 | super(handleMapValue(map, charset), Consts.MIME_TYPE_FORM_URLENCODE, charset);
39 | }
40 |
41 | private static String handleMapValue(Map map, String charset) {
42 | if (map == null) {
43 | return "";
44 | }
45 | StringBuilder sb = new StringBuilder();
46 | boolean isF = true;
47 | for (Map.Entry entry : map.entrySet()) {
48 | if (!isF)
49 | sb.append(Consts.AND);
50 | else
51 | isF = false;
52 | try {
53 | sb.append(URLEncoder.encode(entry.getKey(), charset))
54 | .append(Consts.EQUALS)
55 | .append(URLEncoder.encode(entry.getValue(), charset));
56 | } catch (UnsupportedEncodingException e) {
57 | e.printStackTrace();
58 | }
59 | }
60 | return sb.toString();
61 | }
62 |
63 | private static String handleListValue(List list, String charset) {
64 | if (list == null) {
65 | return "";
66 | }
67 | StringBuilder sb = new StringBuilder();
68 | boolean isF = true;
69 | for (NameValuePair p : list) {
70 | if (!isF)
71 | sb.append(Consts.AND);
72 | else
73 | isF = false;
74 | try {
75 | sb.append(URLEncoder.encode(p.getName(), charset))
76 | .append(Consts.EQUALS)
77 | .append(URLEncoder.encode(p.getValue(), charset));
78 | } catch (UnsupportedEncodingException e) {
79 | e.printStackTrace();
80 | }
81 | }
82 | return sb.toString();
83 | }
84 |
85 |
86 | @Override
87 | public String toString() {
88 | return "StringEntity{" +
89 | "string='" + string + '\'' +
90 | ", charset='" + charset + '\'' +
91 | ", contentType='" + contentType + '\'' +
92 | '}';
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/request/content/multi/AbstractPart.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.request.content.multi;
2 |
3 | import com.litesuits.http.data.Consts;
4 | import com.litesuits.http.utils.StringCodingUtils;
5 |
6 | import java.io.ByteArrayOutputStream;
7 | import java.io.IOException;
8 | import java.io.OutputStream;
9 | import java.nio.charset.Charset;
10 |
11 | /**
12 | * 抽象上传类
13 | *
14 | * @author MaTianyu
15 | * @date 14-7-29
16 | */
17 | public abstract class AbstractPart {
18 |
19 | protected static final Charset infoCharset = BoundaryCreater.charset;
20 | public static final byte[] CR_LF = StringCodingUtils.getBytes("\r\n", infoCharset);
21 | public static final byte[] TRANSFER_ENCODING_BINARY =
22 | StringCodingUtils.getBytes("Content-Transfer-Encoding: binary\r\n", infoCharset);
23 | public static final byte[] TRANSFER_ENCODING_8BIT =
24 | StringCodingUtils.getBytes("Content-Transfer-Encoding: 8bit\r\n", infoCharset);
25 |
26 |
27 | protected String key;
28 | public byte[] header;
29 | protected String mimeType = Consts.MIME_TYPE_OCTET_STREAM;
30 | protected MultipartBody multipartBody;
31 |
32 | protected AbstractPart(String key, String mimeType) {
33 | this.key = key;
34 | if (mimeType != null) {
35 | this.mimeType = mimeType;
36 | }
37 | }
38 |
39 | //此方法需要被调用以产生header(开发者无需自己调用,Entity会调用它)
40 | public byte[] createHeader(byte[] boundaryLine) {
41 | ByteArrayOutputStream headerStream = new ByteArrayOutputStream();
42 | try {
43 | headerStream.write(boundaryLine);
44 | headerStream.write(createContentDisposition());
45 | headerStream.write(createContentType());
46 | headerStream.write(getTransferEncoding());
47 | headerStream.write(CR_LF);
48 | header = headerStream.toByteArray();
49 | } catch (IOException e) {
50 | e.printStackTrace();
51 | }
52 | return header;
53 | }
54 |
55 | protected abstract byte[] createContentType();
56 |
57 | protected abstract byte[] createContentDisposition();
58 |
59 | public abstract long getTotalLength() throws IOException;
60 |
61 | public abstract byte[] getTransferEncoding();
62 |
63 | public abstract void writeTo(OutputStream out) throws IOException;
64 |
65 | public void writeToServer(OutputStream out) throws IOException {
66 | if (header == null) {
67 | throw new RuntimeException("Not call createHeader(),未调用createHeader方法");
68 | }
69 | out.write(header);
70 | updateProgress(header.length);
71 | writeTo(out);
72 | }
73 |
74 | public MultipartBody getMultipartBody() {
75 | return multipartBody;
76 | }
77 |
78 | public void setMultipartBody(MultipartBody multipartBody) {
79 | this.multipartBody = multipartBody;
80 | }
81 |
82 | protected void updateProgress(int length) {
83 | if (multipartBody != null) {
84 | multipartBody.updateProgress(length);
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/request/content/multi/BoundaryCreater.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.request.content.multi;
2 |
3 | import com.litesuits.http.data.Consts;
4 | import com.litesuits.http.utils.StringCodingUtils;
5 |
6 | import java.nio.charset.Charset;
7 | import java.util.Random;
8 |
9 | /**
10 | * @author MaTianyu
11 | * @date 2014-08-06
12 | */
13 | public class BoundaryCreater {
14 | public static final Charset charset = Charset.forName(Consts.DEFAULT_CHARSET);
15 | private final static char[] MULTIPART_CHARS = "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
16 | private String boundary;
17 | private byte[] boundaryLine;
18 | private byte[] boundaryEnd;
19 |
20 | public BoundaryCreater() {
21 | final StringBuilder buf = new StringBuilder();
22 | final Random rand = new Random();
23 | for (int i = 0; i < 30; i++) {
24 | buf.append(MULTIPART_CHARS[rand.nextInt(MULTIPART_CHARS.length)]);
25 | }
26 | boundary = buf.toString();
27 | boundaryLine = StringCodingUtils.getBytes("--" + boundary + "\r\n", charset);
28 | boundaryEnd = StringCodingUtils.getBytes("--" + boundary + "--\r\n", charset);
29 | }
30 |
31 | public String getBoundary() {
32 | return boundary;
33 | }
34 |
35 | public byte[] getBoundaryLine() {
36 | return boundaryLine;
37 | }
38 |
39 | public byte[] getBoundaryEnd() {
40 | return boundaryEnd;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/request/content/multi/BytesPart.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.request.content.multi;
2 |
3 | import com.litesuits.http.log.HttpLog;
4 | import com.litesuits.http.data.Consts;
5 | import com.litesuits.http.utils.StringCodingUtils;
6 |
7 | import java.io.IOException;
8 | import java.io.OutputStream;
9 |
10 | /**
11 | * 上传字节
12 | *
13 | * @author MaTianyu
14 | * @date 14-7-29
15 | */
16 | public class BytesPart extends AbstractPart {
17 | public byte[] bytes;
18 | public static final String TAG = BytesPart.class.getSimpleName();
19 | //protected String type = Consts.MIME_TYPE_OCTET_STREAM;
20 |
21 | public BytesPart(String key, byte[] bytes) {
22 | this(key, bytes, null);
23 | this.bytes = bytes;
24 | }
25 |
26 | public BytesPart(String key, byte[] bytes, String mimeType) {
27 | super(key, mimeType);
28 | this.bytes = bytes;
29 | }
30 |
31 | @Override
32 | protected byte[] createContentType() {
33 | return StringCodingUtils.getBytes(Consts.CONTENT_TYPE + ": " + mimeType + "\r\n", infoCharset);
34 | }
35 |
36 | @Override
37 | protected byte[] createContentDisposition() {
38 | return StringCodingUtils.getBytes("Content-Disposition: form-data; name=\"" + key + "\"\r\n", infoCharset);
39 | }
40 |
41 | public long getTotalLength() {
42 | if (HttpLog.isPrint) if (HttpLog.isPrint) HttpLog.v(TAG, TAG + "内容长度 header : " + header.length + " ,body: "
43 | + bytes.length + " ," + "换行:" + CR_LF.length);
44 | return header.length + bytes.length + CR_LF.length;
45 | }
46 |
47 | @Override
48 | public byte[] getTransferEncoding() {
49 | return TRANSFER_ENCODING_BINARY;
50 | }
51 |
52 | @Override
53 | public void writeTo(OutputStream out) throws IOException {
54 | out.write(bytes);
55 | out.write(CR_LF);
56 | updateProgress(bytes.length + CR_LF.length);
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/request/content/multi/FilePart.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.request.content.multi;
2 |
3 | import com.litesuits.http.log.HttpLog;
4 | import com.litesuits.http.data.Consts;
5 | import com.litesuits.http.request.content.HttpBody;
6 | import com.litesuits.http.utils.StringCodingUtils;
7 |
8 | import java.io.*;
9 |
10 | /**
11 | * 上传文件
12 | *
13 | * @author MaTianyu
14 | * @date 14-7-29
15 | */
16 | public class FilePart extends AbstractPart {
17 | public File file;
18 | public static final String TAG = FilePart.class.getSimpleName();
19 |
20 | public FilePart(String key, File file) {
21 | this(key, file, Consts.MIME_TYPE_OCTET_STREAM);
22 | }
23 |
24 | public FilePart(String key, File file, String mimeType) {
25 | super(key, mimeType);
26 | this.file = file;
27 | }
28 |
29 | @Override
30 | protected byte[] createContentType() {
31 | return StringCodingUtils.getBytes(Consts.CONTENT_TYPE + ": " + mimeType + "\r\n", infoCharset);
32 | }
33 |
34 | @Override
35 | protected byte[] createContentDisposition() {
36 | String dis = "Content-Disposition: form-data; name=\"" + key;
37 | return StringCodingUtils.getBytes(dis + "\"; filename=\"" + file.getName() + "\"\r\n", infoCharset);
38 | }
39 |
40 |
41 | public long getTotalLength() {
42 | long len = file.length();
43 | if (HttpLog.isPrint) {
44 | HttpLog.v(TAG, TAG + " 内容长度header : " + header.length
45 | + " ,body: " + len + " ," + "换行:" + CR_LF.length);
46 | }
47 | return header.length + len + CR_LF.length;
48 | }
49 |
50 | @Override
51 | public byte[] getTransferEncoding() {
52 | return TRANSFER_ENCODING_BINARY;
53 | }
54 |
55 | public void writeTo(OutputStream out) throws IOException {
56 | final InputStream instream = new FileInputStream(this.file);
57 | try {
58 | final byte[] tmp = new byte[HttpBody.OUTPUT_BUFFER_SIZE];
59 | int l;
60 | while ((l = instream.read(tmp)) != -1) {
61 | out.write(tmp, 0, l);
62 | updateProgress(l);
63 | }
64 | out.write(CR_LF);
65 | updateProgress(CR_LF.length);
66 | out.flush();
67 | } catch (IOException e) {
68 | e.printStackTrace();
69 | } finally {
70 | instream.close();
71 | }
72 | }
73 |
74 | }
75 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/request/content/multi/InputStreamPart.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.request.content.multi;
2 |
3 | import com.litesuits.http.log.HttpLog;
4 | import com.litesuits.http.data.Consts;
5 | import com.litesuits.http.request.content.HttpBody;
6 | import com.litesuits.http.utils.StringCodingUtils;
7 |
8 | import java.io.IOException;
9 | import java.io.InputStream;
10 | import java.io.OutputStream;
11 |
12 | /**
13 | * 上传数据流
14 | *
15 | * @author MaTianyu
16 | * @date 14-7-29
17 | */
18 | public class InputStreamPart extends AbstractPart {
19 | protected InputStream inputStream;
20 |
21 | protected static final String TAG = InputStreamPart.class.getSimpleName();
22 | protected String fileName;
23 |
24 | public InputStreamPart(String key, InputStream inputStream) {
25 | this(key, inputStream, null, Consts.MIME_TYPE_OCTET_STREAM);
26 | }
27 |
28 | public InputStreamPart(String key, InputStream inputStream, String contentType) {
29 | this(key, inputStream, null, contentType);
30 | }
31 |
32 | public InputStreamPart(String key, InputStream inputStream, String fileName, String mimeType) {
33 | super(key, mimeType);
34 | if (inputStream == null) {
35 | throw new NullPointerException("InputStream not be null !");
36 | }
37 | this.inputStream = inputStream;
38 | this.fileName = fileName;
39 | }
40 |
41 | @Override
42 | protected byte[] createContentType() {
43 | return StringCodingUtils.getBytes(Consts.CONTENT_TYPE + ": " + mimeType + "\r\n", infoCharset);
44 | }
45 |
46 | @Override
47 | protected byte[] createContentDisposition() {
48 | String dis = "Content-Disposition: form-data; name=\"" + key;
49 | return fileName == null ? StringCodingUtils.getBytes(dis + "\"\r\n", infoCharset)
50 | : StringCodingUtils.getBytes(dis + "\"; filename=\"" + fileName + "\"\r\n", infoCharset);
51 | }
52 |
53 | @Override
54 | public long getTotalLength() throws IOException {
55 | long len = inputStream.available();
56 | if (HttpLog.isPrint) {
57 | HttpLog.v(TAG, TAG + "内容长度 header : " + header.length + " ,body: " + len + " ," +
58 | "换行:" + CR_LF.length);
59 | }
60 | return header.length + len + CR_LF.length;
61 | }
62 |
63 | @Override
64 | public byte[] getTransferEncoding() {
65 | return TRANSFER_ENCODING_BINARY;
66 | }
67 |
68 | public void writeTo(OutputStream out) throws IOException {
69 | try {
70 | final byte[] tmp = new byte[HttpBody.OUTPUT_BUFFER_SIZE];
71 | int l;
72 | while ((l = inputStream.read(tmp)) != -1) {
73 | out.write(tmp, 0, l);
74 | updateProgress(l);
75 | }
76 | out.write(CR_LF);
77 | updateProgress(CR_LF.length);
78 | out.flush();
79 | } catch (final IOException e) {
80 | e.printStackTrace();
81 | } finally {
82 | if (inputStream != null)
83 | inputStream.close();
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/request/content/multi/MultipartBody.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.request.content.multi;
2 |
3 | import com.litesuits.http.data.Consts;
4 | import com.litesuits.http.request.content.HttpBody;
5 |
6 | import java.io.*;
7 | import java.util.LinkedList;
8 |
9 | /**
10 | * @author MaTianyu
11 | * @date 14-7-29
12 | */
13 | public class MultipartBody extends HttpBody {
14 | private LinkedList httpParts = new LinkedList();
15 | private long totalSize;
16 | private long bytesWritten;
17 | BoundaryCreater boundaryCreater;
18 |
19 | public MultipartBody() {
20 | boundaryCreater = new BoundaryCreater();
21 | contentType = Consts.MIME_TYPE_FORM_DATA + Consts.BOUNDARY_PARAM + boundaryCreater.getBoundary();
22 | }
23 |
24 | public LinkedList getHttpParts() {
25 | return httpParts;
26 | }
27 |
28 | public MultipartBody setHttpParts(LinkedList httpParts) {
29 | this.httpParts = httpParts;
30 | return this;
31 | }
32 |
33 | public MultipartBody addPart(String key, String string, String charset, String mimeType) throws
34 | UnsupportedEncodingException {
35 | return addPart(new StringPart(key, string, charset, mimeType));
36 | }
37 |
38 | public MultipartBody addPart(String key, byte[] bytes, String mimeType) {
39 | return addPart(new BytesPart(key, bytes, mimeType));
40 | }
41 |
42 | public MultipartBody addPart(String key, File file, String mimeType) throws FileNotFoundException {
43 | return addPart(new FilePart(key, file, mimeType));
44 | }
45 |
46 | public MultipartBody addPart(String key, InputStream inputStream, String fileName, String mimeType) {
47 | return addPart(new InputStreamPart(key, inputStream, fileName, mimeType));
48 | }
49 |
50 | public MultipartBody addPart(AbstractPart part) {
51 | if (part == null) {
52 | return this;
53 | }
54 | // note that: set multibody to every part, so that we can get progress of these part.
55 | part.setMultipartBody(this);
56 | part.createHeader(boundaryCreater.getBoundaryLine());
57 | httpParts.add(part);
58 | return this;
59 | }
60 |
61 | public long getContentLength() {
62 | long contentLen = -1;
63 | try {
64 | for (AbstractPart part : httpParts) {
65 | long len = 0;
66 | len = part.getTotalLength();
67 | if (len < 0) {
68 | return -1;
69 | }
70 | contentLen += len;
71 | }
72 | contentLen += boundaryCreater.getBoundaryEnd().length;
73 | } catch (IOException e) {
74 | e.printStackTrace();
75 | }
76 | return contentLen;
77 | }
78 |
79 | public void writeTo(final OutputStream outstream) throws IOException {
80 | bytesWritten = 0;
81 | totalSize = (int) getContentLength();
82 | for (AbstractPart part : httpParts) {
83 | part.writeToServer(outstream);
84 | }
85 | outstream.write(boundaryCreater.getBoundaryEnd());
86 | updateProgress(boundaryCreater.getBoundaryEnd().length);
87 | }
88 |
89 | @SuppressWarnings("unchecked")
90 | protected void updateProgress(long count) {
91 | bytesWritten += count;
92 | if (httpListener != null) {
93 | httpListener.notifyCallUploading(request, totalSize, bytesWritten);
94 | }
95 | }
96 |
97 | public BoundaryCreater getBoundary() {
98 | return boundaryCreater;
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/request/content/multi/StringPart.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.request.content.multi;
2 |
3 | import com.litesuits.http.data.Consts;
4 | import com.litesuits.http.utils.StringCodingUtils;
5 |
6 | import java.io.UnsupportedEncodingException;
7 |
8 | /**
9 | * @author MaTianyu
10 | * @date 14-7-29
11 | */
12 | public class StringPart extends BytesPart {
13 | protected String charset;
14 | protected String mimeType;
15 |
16 | public StringPart(String key, String string) {
17 | this(key, string, Consts.DEFAULT_CHARSET, Consts.MIME_TYPE_TEXT);
18 | }
19 |
20 | public StringPart(String key, String string, String charset, String mimeType) {
21 | super(key, getBytes(string, charset),mimeType);
22 | this.mimeType = mimeType != null ? mimeType : Consts.MIME_TYPE_TEXT;
23 | this.charset = charset;
24 | }
25 |
26 | public static byte[] getBytes(String string, String charset) {
27 | try {
28 | return string.getBytes(charset);
29 | } catch (UnsupportedEncodingException e) {
30 | e.printStackTrace();
31 | }
32 | return null;
33 | }
34 |
35 | @Override
36 | protected byte[] createContentType() {
37 | return StringCodingUtils.getBytes(Consts.CONTENT_TYPE + ": " + mimeType + " " + Consts.CHARSET_PARAM + charset +
38 | "\r\n", infoCharset);
39 | }
40 |
41 | @Override
42 | public byte[] getTransferEncoding() {
43 | return TRANSFER_ENCODING_8BIT;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/request/param/CacheMode.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.request.param;
2 |
3 | /**
4 | * @author MaTianyu
5 | * @date 2015-04-22
6 | */
7 | public enum CacheMode {
8 | NetOnly,
9 | NetFirst,
10 | CacheFirst,
11 | CacheOnly
12 | }
13 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/request/param/HttpCustomParam.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.request.param;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * help to build custom parameters for {@link com.litesuits.http.request.AbstractRequest}
10 | *
11 | * @author MaTianyu
12 | * 2014-1-1上午2:45:11
13 | */
14 | public interface HttpCustomParam {
15 |
16 | @Target(ElementType.METHOD)
17 | @Retention(RetentionPolicy.RUNTIME)
18 | public @interface CustomValueBuilder {}
19 |
20 | @CustomValueBuilder
21 | public CharSequence buildValue();
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/request/param/HttpMethods.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.request.param;
2 |
3 | /**
4 | * support method
5 | *
6 | * @author MaTianyu
7 | * 2014-1-1下午9:51:59
8 | */
9 | public enum HttpMethods {
10 | /* ******************* Http Get(Query) Request *************/
11 | /**
12 | * get
13 | */
14 | Get("GET"),
15 | /**
16 | * get http header only
17 | */
18 | Head("HEAD"),
19 | /**
20 | * debug
21 | */
22 | Trace("TRACE"),
23 | /**
24 | * query
25 | */
26 | Options("OPTIONS"),
27 | /**
28 | * delete
29 | */
30 | Delete("DELETE"),
31 | /* ******************* Http Upate(Entity Enclosing) Request *************/
32 | /**
33 | * update
34 | */
35 | Put("PUT"),
36 | /**
37 | * add
38 | */
39 | Post("POST"),
40 | /**
41 | * incremental update
42 | */
43 | Patch("PATCH");
44 |
45 | private String methodName;
46 |
47 | HttpMethods(String methodName) {
48 | this.methodName = methodName;
49 | }
50 |
51 | public String getMethodName() {
52 | return methodName;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/request/param/HttpParam.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.request.param;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author MaTianyu @http://litesuits.com
10 | * @date 2015-11-13
11 | */
12 | @Target(ElementType.FIELD)
13 | @Retention(RetentionPolicy.RUNTIME)
14 | public @interface HttpParam {
15 | String value();
16 | }
17 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/request/param/HttpParamModel.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.request.param;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * mark a class as a http parameter modle.
7 | * classes that implement this will be parsed to http parameter.
8 | *
9 | * @author MaTianyu
10 | * 2014-1-19上午2:39:31
11 | */
12 | public interface HttpParamModel extends Serializable{}
13 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/request/param/HttpReplace.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.request.param;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author MaTianyu @http://litesuits.com
10 | * @date 2015-11-18
11 | */
12 | @Target(ElementType.FIELD)
13 | @Retention(RetentionPolicy.RUNTIME)
14 | public @interface HttpReplace {
15 | String value();
16 | }
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/request/param/HttpRichParamModel.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.request.param;
2 |
3 | import com.litesuits.http.listener.HttpListener;
4 | import com.litesuits.http.request.JsonRequest;
5 | import com.litesuits.http.request.content.HttpBody;
6 | import com.litesuits.http.request.content.StringBody;
7 | import com.litesuits.http.request.content.UrlEncodedFormBody;
8 | import com.litesuits.http.request.content.multi.MultipartBody;
9 | import com.litesuits.http.request.query.ModelQueryBuilder;
10 |
11 | import java.lang.reflect.ParameterizedType;
12 | import java.lang.reflect.Type;
13 | import java.util.LinkedHashMap;
14 |
15 | /**
16 | * mark a class as a http parameter modle.
17 | * classes that implement this will be parsed to http parameter.
18 | * 杂袍1只, 墨兰1对, 大红1对, 红鼻10条,金光10条,玻璃扯旗10条,三角10条,红绿灯10条。
19 | *
20 | * @author MaTianyu
21 | * 2014-1-19上午2:39:31
22 | */
23 | public abstract class HttpRichParamModel implements HttpParamModel {
24 | private HttpListener httpListener;
25 |
26 | public final LinkedHashMap getHeaders() {
27 | return createHeaders();
28 | }
29 |
30 | public ModelQueryBuilder getModelQueryBuilder() {
31 | return createQueryBuilder();
32 | }
33 |
34 | public final HttpBody getHttpBody() {
35 | return createHttpBody();
36 | }
37 |
38 | public final HttpListener getHttpListener() {
39 | if (httpListener == null) {
40 | httpListener = createHttpListener();
41 | }
42 | return httpListener;
43 | }
44 |
45 | public boolean isFieldsAttachToUrl() {
46 | return true;
47 | }
48 |
49 | /**
50 | * craete headers for request.
51 | */
52 | protected LinkedHashMap createHeaders() {return null;}
53 |
54 | /**
55 | * craete uri query builder for request.
56 | */
57 | protected ModelQueryBuilder createQueryBuilder() {
58 | return null;
59 | }
60 |
61 | /**
62 | * create http body for POST/PUT... request.
63 | *
64 | * @return such as {@link StringBody}, {@link UrlEncodedFormBody}, {@link MultipartBody}...
65 | */
66 | protected HttpBody createHttpBody() {return null;}
67 |
68 | /**
69 | * create http listener for request.
70 | */
71 | protected HttpListener createHttpListener() {return null;}
72 |
73 | /**
74 | * build request and set http listener.
75 | */
76 | @SuppressWarnings("unchecked")
77 | public final > M setHttpListener(HttpListener httpListener) {
78 | this.httpListener = httpListener;
79 | return (M) this;
80 | }
81 |
82 | /**
83 | * build as a request.
84 | */
85 | public JsonRequest buildRequest() {
86 | Type type = ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
87 | return new JsonRequest(this, type);
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/request/param/NonHttpParam.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.request.param;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * marked for java field that exclude from http parameter.
10 | *
11 | * @author MaTianyu
12 | * 2014-1-19下午11:57:47
13 | */
14 | @Target(ElementType.FIELD)
15 | @Retention(RetentionPolicy.RUNTIME)
16 | public @interface NonHttpParam {}
17 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/request/query/JsonQueryBuilder.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.request.query;
2 |
3 | import com.litesuits.http.data.Json;
4 |
5 | /**
6 | * when uri query parameter's value is complicated, build value into json.
7 | * in this case, value will intelligently translate to json string.
8 | *
9 | * such as:
10 | * http://def.so? key1 = value.toJsonString() & key2 = value.toJsonString()
11 | *
12 | * @author MaTianyu
13 | * 2014-1-4下午5:06:37
14 | */
15 | public class JsonQueryBuilder extends ModelQueryBuilder {
16 |
17 | @Override
18 | protected CharSequence buildSencondaryValue(Object model) {
19 | try {
20 | return Json.get().toJson(model);
21 | } catch (Exception e) {
22 | e.printStackTrace();
23 | }
24 | return null;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/response/Response.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.response;
2 |
3 | import com.litesuits.http.data.HttpStatus;
4 | import com.litesuits.http.data.NameValuePair;
5 | import com.litesuits.http.exception.HttpException;
6 | import com.litesuits.http.request.AbstractRequest;
7 |
8 | import java.util.ArrayList;
9 |
10 | /**
11 | * User Facade
12 | * providing developers with easy access to the results of
13 | * {@link com.litesuits.http.LiteHttp#execute(AbstractRequest)},
14 | * and with information of status,request,charset,etc.
15 | *
16 | * @author MaTianyu
17 | * 2014-1-1下午10:00:42
18 | */
19 | public interface Response {
20 |
21 |
22 | ArrayList getHeaders();
23 |
24 | HttpStatus getHttpStatus();
25 |
26 | T getResult();
27 |
28 | > R getRequest();
29 |
30 | long getReadedLength();
31 |
32 | long getContentLength();
33 |
34 |
35 | String getContentEncoding();
36 |
37 | String getContentType();
38 |
39 | String getCharSet();
40 |
41 | long getUseTime();
42 |
43 | boolean isConnectSuccess();
44 |
45 | int getRetryTimes();
46 |
47 | int getRedirectTimes();
48 |
49 | HttpException getException();
50 |
51 | boolean isCacheHit();
52 |
53 | String getRawString();
54 |
55 | Response setTag(Object tag);
56 |
57 | Object getTag();
58 |
59 | String resToString();
60 |
61 | void printInfo();
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/utils/MD5Util.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.utils;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import java.security.MessageDigest;
6 | import java.security.NoSuchAlgorithmException;
7 |
8 | /**
9 | * MS5
10 | */
11 | public class MD5Util {
12 | private static final String TAG = MD5Util.class.getSimpleName();
13 | private static final int STREAM_BUFFER_LENGTH = 1024;
14 |
15 | public static MessageDigest getDigest(final String algorithm) throws NoSuchAlgorithmException {
16 | return MessageDigest.getInstance(algorithm);
17 | }
18 |
19 | public static byte[] md5(String txt) {
20 | return md5(txt.getBytes());
21 | }
22 |
23 | public static byte[] md5(byte[] bytes) {
24 | try {
25 | MessageDigest digest = getDigest("MD5");
26 | digest.update(bytes);
27 | return digest.digest();
28 | } catch (NoSuchAlgorithmException e) {
29 | e.printStackTrace();
30 | }
31 | return null;
32 | }
33 |
34 | public static byte[] md5(InputStream is) throws NoSuchAlgorithmException, IOException {
35 | return updateDigest(getDigest("MD5"), is).digest();
36 | }
37 |
38 | public static MessageDigest updateDigest(final MessageDigest digest, final InputStream data) throws IOException {
39 | final byte[] buffer = new byte[STREAM_BUFFER_LENGTH];
40 | int read = data.read(buffer, 0, STREAM_BUFFER_LENGTH);
41 |
42 | while (read > -1) {
43 | digest.update(buffer, 0, read);
44 | read = data.read(buffer, 0, STREAM_BUFFER_LENGTH);
45 | }
46 |
47 | return digest;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/utils/StringCodingUtils.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.utils;
2 |
3 | import android.os.Build;
4 |
5 | import java.io.UnsupportedEncodingException;
6 | import java.nio.charset.Charset;
7 |
8 | /**
9 | * @author MaTianyu
10 | * @date 2014-12-05
11 | */
12 | public class StringCodingUtils {
13 |
14 | public static byte[] getBytes(String src, Charset charSet) {
15 | // Build.VERSION_CODES.GINGERBREAD = 9
16 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD) {
17 | try {
18 | return src.getBytes(charSet.name());
19 | } catch (UnsupportedEncodingException e) {
20 | e.printStackTrace();
21 | }
22 | return null;
23 | } else {
24 | return src.getBytes(charSet);
25 | }
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/litehttp/src/main/java/com/litesuits/http/utils/UriUtil.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http.utils;
2 |
3 | import android.net.Uri;
4 |
5 | import java.util.*;
6 |
7 | /**
8 | * @author matianyu
9 | * @date 2015-04-24
10 | */
11 | public class UriUtil {
12 | /**
13 | * Returns a set of the unique names of all query parameters. Iterating
14 | * over the set will return the names in order of their first occurrence.
15 | *
16 | * @return a set of decoded names
17 | * @throws UnsupportedOperationException if this isn't a hierarchical URI
18 | */
19 | public static Set getQueryParameterNames(Uri uri) {
20 | if (uri.isOpaque()) {
21 | return Collections.emptySet();
22 | }
23 |
24 | String query = uri.getEncodedQuery();
25 | if (query == null) {
26 | return Collections.emptySet();
27 | }
28 |
29 | Set names = new LinkedHashSet();
30 | int start = 0;
31 | do {
32 | int next = query.indexOf('&', start);
33 | int end = (next == -1) ? query.length() : next;
34 |
35 | int separator = query.indexOf('=', start);
36 | if (separator > end || separator == -1) {
37 | separator = end;
38 | }
39 |
40 | String name = query.substring(start, separator);
41 | names.add(name);
42 | // Move start to end of name.
43 | start = end + 1;
44 | } while (start < query.length());
45 |
46 | return Collections.unmodifiableSet(names);
47 | }
48 |
49 | /**
50 | * Searches the query string for parameter values with the given key.
51 | *
52 | * @param key which will be encoded
53 | * @return a list of decoded values
54 | * @throws UnsupportedOperationException if this isn't a hierarchical URI
55 | * @throws NullPointerException if key is null
56 | */
57 | public static List getQueryParameters(Uri uri, String key) {
58 | if (uri.isOpaque()) {
59 | return Collections.emptyList();
60 | }
61 | if (key == null) {
62 | throw new NullPointerException("key");
63 | }
64 |
65 | String query = uri.getEncodedQuery();
66 | if (query == null) {
67 | return Collections.emptyList();
68 | }
69 |
70 | ArrayList values = new ArrayList();
71 |
72 | int start = 0;
73 | do {
74 | int nextAmpersand = query.indexOf('&', start);
75 | int end = nextAmpersand != -1 ? nextAmpersand : query.length();
76 |
77 | int separator = query.indexOf('=', start);
78 | if (separator > end || separator == -1) {
79 | separator = end;
80 | }
81 |
82 | if (separator - start == key.length()
83 | && query.regionMatches(start, key, 0, key.length())) {
84 | if (separator == end) {
85 | values.add("");
86 | } else {
87 | values.add(query.substring(separator + 1, end));
88 | }
89 | }
90 |
91 | // Move start to end of name.
92 | if (nextAmpersand != -1) {
93 | start = nextAmpersand + 1;
94 | } else {
95 | break;
96 | }
97 | } while (true);
98 |
99 | return Collections.unmodifiableList(values);
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/litehttp/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | litehttp3
3 |
4 |
--------------------------------------------------------------------------------
/litehttp/src/test/java/com/litesuits/http/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.litesuits.http;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 | assertEquals(4, 2 + 2);
14 | }
15 | }
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':litehttp-sample', ':litehttp', ':apache-client'
2 |
--------------------------------------------------------------------------------
/web-server-sample/lib/javax.annotation.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/web-server-sample/lib/javax.annotation.jar
--------------------------------------------------------------------------------
/web-server-sample/lib/javax.ejb.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/web-server-sample/lib/javax.ejb.jar
--------------------------------------------------------------------------------
/web-server-sample/lib/javax.jms.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/web-server-sample/lib/javax.jms.jar
--------------------------------------------------------------------------------
/web-server-sample/lib/javax.persistence.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/web-server-sample/lib/javax.persistence.jar
--------------------------------------------------------------------------------
/web-server-sample/lib/javax.resource.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/web-server-sample/lib/javax.resource.jar
--------------------------------------------------------------------------------
/web-server-sample/lib/javax.servlet.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/web-server-sample/lib/javax.servlet.jar
--------------------------------------------------------------------------------
/web-server-sample/lib/javax.servlet.jsp.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/web-server-sample/lib/javax.servlet.jsp.jar
--------------------------------------------------------------------------------
/web-server-sample/lib/javax.servlet.jsp.jstl.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/web-server-sample/lib/javax.servlet.jsp.jstl.jar
--------------------------------------------------------------------------------
/web-server-sample/lib/javax.transaction.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/web-server-sample/lib/javax.transaction.jar
--------------------------------------------------------------------------------
/web-server-sample/web/WEB-INF/lib/commons-codec-1.9.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/web-server-sample/web/WEB-INF/lib/commons-codec-1.9.jar
--------------------------------------------------------------------------------
/web-server-sample/web/WEB-INF/lib/commons-fileupload-1.3.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/web-server-sample/web/WEB-INF/lib/commons-fileupload-1.3.1.jar
--------------------------------------------------------------------------------
/web-server-sample/web/WEB-INF/lib/commons-io-2.4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/web-server-sample/web/WEB-INF/lib/commons-io-2.4.jar
--------------------------------------------------------------------------------
/web-server-sample/web/WEB-INF/lib/commons-logging-1.2.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/web-server-sample/web/WEB-INF/lib/commons-logging-1.2.jar
--------------------------------------------------------------------------------
/web-server-sample/web/WEB-INF/lib/fluent-hc-4.4.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/web-server-sample/web/WEB-INF/lib/fluent-hc-4.4.1.jar
--------------------------------------------------------------------------------
/web-server-sample/web/WEB-INF/lib/httpclient-4.4.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/web-server-sample/web/WEB-INF/lib/httpclient-4.4.1.jar
--------------------------------------------------------------------------------
/web-server-sample/web/WEB-INF/lib/httpclient-cache-4.4.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/web-server-sample/web/WEB-INF/lib/httpclient-cache-4.4.1.jar
--------------------------------------------------------------------------------
/web-server-sample/web/WEB-INF/lib/httpclient-win-4.4.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/web-server-sample/web/WEB-INF/lib/httpclient-win-4.4.1.jar
--------------------------------------------------------------------------------
/web-server-sample/web/WEB-INF/lib/httpcore-4.4.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/web-server-sample/web/WEB-INF/lib/httpcore-4.4.1.jar
--------------------------------------------------------------------------------
/web-server-sample/web/WEB-INF/lib/httpmime-4.4.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/web-server-sample/web/WEB-INF/lib/httpmime-4.4.1.jar
--------------------------------------------------------------------------------
/web-server-sample/web/WEB-INF/lib/jna-4.1.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/web-server-sample/web/WEB-INF/lib/jna-4.1.0.jar
--------------------------------------------------------------------------------
/web-server-sample/web/WEB-INF/lib/jna-platform-4.1.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litesuits/android-lite-http/20e469814edb818cfab5e9b61aaeb034cc517fac/web-server-sample/web/WEB-INF/lib/jna-platform-4.1.0.jar
--------------------------------------------------------------------------------
/web-server-sample/web/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
--------------------------------------------------------------------------------
/web-server-sample/web/index.jsp:
--------------------------------------------------------------------------------
1 | <%--
2 | Created by IntelliJ IDEA.
3 | User: MaTianyu
4 | Date: 15/5/3
5 | Time: 下午8:23
6 | To change this template use File | Settings | File Templates.
7 | --%>
8 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
9 |
10 |
11 | hello world
12 |
13 |
14 | hello world!
15 | This is a server client sample for litehttp-v3
16 |
17 |
18 |
--------------------------------------------------------------------------------