getResult(@Query("token") String token);
38 | }
39 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lighters/demos/token/http/api/ResultModel.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 david.wei (lighters)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.lighters.demos.token.http.api;
18 |
19 | /**
20 | * Created by david on 16/8/20.
21 | * Email: huangdiv5@gmail.com
22 | * GitHub: https://github.com/alighters
23 | */
24 | public class ResultModel {
25 |
26 | /**
27 | * result : false
28 | */
29 |
30 | public boolean result;
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lighters/demos/token/http/api/TokenModel.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 david.wei (lighters)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.lighters.demos.token.http.api;
18 |
19 | /**
20 | * Created by david on 16/8/20.
21 | * Email: huangdiv5@gmail.com
22 | * GitHub: https://github.com/alighters
23 | */
24 | public class TokenModel {
25 |
26 | public String token;
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lighters/demos/token/http/converter/GsonConverterFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Square, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.lighters.demos.token.http.converter;
18 |
19 | import com.google.gson.Gson;
20 | import com.google.gson.TypeAdapter;
21 | import com.google.gson.reflect.TypeToken;
22 | import com.lighters.demos.token.http.api.ApiModel;
23 | import java.lang.annotation.Annotation;
24 | import java.lang.reflect.ParameterizedType;
25 | import java.lang.reflect.Type;
26 | import okhttp3.RequestBody;
27 | import okhttp3.ResponseBody;
28 | import retrofit2.Converter;
29 | import retrofit2.Retrofit;
30 |
31 | /**
32 | * A {@linkplain Converter.Factory converter} which uses Gson for JSON.
33 | *
34 | * Because Gson is so flexible in the types it supports, this converter assumes that it can handle
35 | * all types. If you are mixing JSON serialization with something else (such as protocol buffers),
36 | * you must {@linkplain Retrofit.Builder#addConverterFactory(Converter.Factory) add this instance}
37 | * last to allow the other converters a chance to see their types.
38 | */
39 | public final class GsonConverterFactory extends Converter.Factory {
40 | /**
41 | * Create an instance using a default {@link Gson} instance for conversion. Encoding to JSON and
42 | * decoding from JSON (when no charset is specified by a header) will use UTF-8.
43 | */
44 | public static GsonConverterFactory create() {
45 | return create(new Gson());
46 | }
47 |
48 | /**
49 | * Create an instance using {@code gson} for conversion. Encoding to JSON and
50 | * decoding from JSON (when no charset is specified by a header) will use UTF-8.
51 | */
52 | public static GsonConverterFactory create(Gson gson) {
53 | return new GsonConverterFactory(gson);
54 | }
55 |
56 | private final Gson gson;
57 |
58 | private GsonConverterFactory(Gson gson) {
59 | if (gson == null) throw new NullPointerException("gson == null");
60 | this.gson = gson;
61 | }
62 |
63 | @Override
64 | public Converter responseBodyConverter(final Type type, Annotation[] annotations, Retrofit retrofit) {
65 | Type newType = new ParameterizedType() {
66 | @Override
67 | public Type[] getActualTypeArguments() {
68 | return new Type[] { type };
69 | }
70 |
71 | @Override
72 | public Type getOwnerType() {
73 | return null;
74 | }
75 |
76 | @Override
77 | public Type getRawType() {
78 | return ApiModel.class;
79 | }
80 | };
81 | TypeAdapter> adapter = gson.getAdapter(TypeToken.get(newType));
82 | return new GsonResponseBodyConverter<>(adapter);
83 | }
84 |
85 | @Override
86 | public Converter, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations,
87 | Annotation[] methodAnnotations, Retrofit retrofit) {
88 | TypeAdapter> adapter = gson.getAdapter(TypeToken.get(type));
89 | return new GsonRequestBodyConverter<>(gson, adapter);
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lighters/demos/token/http/converter/GsonRequestBodyConverter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Square, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.lighters.demos.token.http.converter;
18 |
19 | import com.google.gson.Gson;
20 | import com.google.gson.TypeAdapter;
21 | import com.google.gson.stream.JsonWriter;
22 | import java.io.IOException;
23 | import java.io.OutputStreamWriter;
24 | import java.io.Writer;
25 | import java.nio.charset.Charset;
26 | import okhttp3.MediaType;
27 | import okhttp3.RequestBody;
28 | import okio.Buffer;
29 | import retrofit2.Converter;
30 |
31 | final class GsonRequestBodyConverter implements Converter {
32 | private static final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8");
33 | private static final Charset UTF_8 = Charset.forName("UTF-8");
34 |
35 | private final Gson gson;
36 | private final TypeAdapter adapter;
37 |
38 | GsonRequestBodyConverter(Gson gson, TypeAdapter adapter) {
39 | this.gson = gson;
40 | this.adapter = adapter;
41 | }
42 |
43 | @Override
44 | public RequestBody convert(T value) throws IOException {
45 | Buffer buffer = new Buffer();
46 | Writer writer = new OutputStreamWriter(buffer.outputStream(), UTF_8);
47 | JsonWriter jsonWriter = gson.newJsonWriter(writer);
48 | adapter.write(jsonWriter, value);
49 | jsonWriter.close();
50 | return RequestBody.create(MEDIA_TYPE, buffer.readByteString());
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lighters/demos/token/http/converter/GsonResponseBodyConverter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Square, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.lighters.demos.token.http.converter;
18 |
19 | import com.google.gson.TypeAdapter;
20 | import com.lighters.demos.token.http.api.ApiModel;
21 | import com.lighters.demos.token.http.api.ErrorCode;
22 | import com.lighters.demos.token.http.exception.ApiException;
23 | import com.lighters.demos.token.http.exception.TokenInvalidException;
24 | import com.lighters.demos.token.http.exception.TokenNotExistException;
25 | import java.io.IOException;
26 | import okhttp3.ResponseBody;
27 | import retrofit2.Converter;
28 |
29 | final class GsonResponseBodyConverter implements Converter {
30 |
31 | private final TypeAdapter adapter;
32 |
33 | GsonResponseBodyConverter(TypeAdapter adapter) {
34 | this.adapter = adapter;
35 | }
36 |
37 | @Override
38 | public Object convert(ResponseBody value) throws IOException {
39 | try {
40 | ApiModel apiModel = (ApiModel) adapter.fromJson(value.charStream());
41 | if (apiModel.errorCode == ErrorCode.TOKEN_NOT_EXIST) {
42 | throw new TokenNotExistException();
43 | } else if (apiModel.errorCode == ErrorCode.TOKEN_INVALID) {
44 | throw new TokenInvalidException();
45 | } else if (!apiModel.success) {
46 | // 特定 API 的错误,在相应的 Subscriber 的 onError 的方法中进行处理
47 | throw new ApiException();
48 | } else if (apiModel.success) {
49 | return apiModel.data;
50 | }
51 | } finally {
52 | value.close();
53 | }
54 | return null;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lighters/demos/token/http/exception/ApiException.java:
--------------------------------------------------------------------------------
1 | package com.lighters.demos.token.http.exception;
2 |
3 | /**
4 | * Created by david on 16/11/24.
5 | * Email: huangdiv5@gmail.com
6 | * GitHub: https://github.com/alighters
7 | *
8 | * 指定 API 的通用错误
9 | */
10 |
11 | public class ApiException extends RuntimeException{
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lighters/demos/token/http/exception/TokenInvalidException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 david.wei (lighters)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.lighters.demos.token.http.exception;
18 |
19 | /**
20 | * Created by david on 16/8/21.
21 | * Email: huangdiv5@gmail.com
22 | * GitHub: https://github.com/alighters
23 | */
24 | public class TokenInvalidException extends RuntimeException {
25 |
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lighters/demos/token/http/exception/TokenNotExistException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 david.wei (lighters)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.lighters.demos.token.http.exception;
18 |
19 | /**
20 | * Created by david on 16/8/21.
21 | * Email: huangdiv5@gmail.com
22 | * GitHub: https://github.com/alighters
23 | */
24 | public class TokenNotExistException extends RuntimeException {
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lighters/demos/token/http/proxy/ProxyHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 david.wei (lighters)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.lighters.demos.token.http.proxy;
18 |
19 | import android.text.TextUtils;
20 | import android.util.Log;
21 | import android.widget.Toast;
22 | import com.lighters.demos.app.base.BaseApplication;
23 | import com.lighters.demos.token.http.GlobalToken;
24 | import com.lighters.demos.token.http.IGlobalManager;
25 | import com.lighters.demos.token.http.RetrofitUtil;
26 | import com.lighters.demos.token.http.api.IApiService;
27 | import com.lighters.demos.token.http.api.TokenModel;
28 | import com.lighters.demos.token.http.exception.TokenInvalidException;
29 | import com.lighters.demos.token.http.exception.TokenNotExistException;
30 | import java.lang.annotation.Annotation;
31 | import java.lang.reflect.InvocationHandler;
32 | import java.lang.reflect.InvocationTargetException;
33 | import java.lang.reflect.Method;
34 | import java.util.Date;
35 | import retrofit2.http.Query;
36 | import rx.Observable;
37 | import rx.Subscriber;
38 | import rx.functions.Func1;
39 |
40 | /**
41 | * Created by david on 16/8/21.
42 | * Email: huangdiv5@gmail.com
43 | * GitHub: https://github.com/alighters
44 | */
45 | public class ProxyHandler implements InvocationHandler {
46 |
47 | private final static String TAG = "Token_Proxy";
48 |
49 | private final static String TOKEN = "token";
50 |
51 | private final static int REFRESH_TOKEN_VALID_TIME = 30;
52 | private static long tokenChangedTime = 0;
53 | private Throwable mRefreshTokenError = null;
54 | private boolean mIsTokenNeedRefresh;
55 |
56 | private Object mProxyObject;
57 | private IGlobalManager mGlobalManager;
58 |
59 | public ProxyHandler(Object proxyObject, IGlobalManager globalManager) {
60 | mProxyObject = proxyObject;
61 | mGlobalManager = globalManager;
62 | }
63 |
64 | @Override
65 | public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
66 | return Observable.just(null).flatMap(new Func1