├── .gitignore ├── .idea ├── dictionaries │ └── gangan.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── README.md ├── api ├── .gitignore ├── build.gradle ├── proguard-rules.txt └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── yanzhenjie │ └── andserver │ ├── AndServer.java │ ├── ComponentRegister.java │ ├── DispatcherHandler.java │ ├── Initialization.java │ ├── SSLInitializer.java │ ├── Server.java │ ├── error │ ├── BasicException.java │ ├── BodyMissingException.java │ ├── ContentNotAcceptableException.java │ ├── ContentNotSupportedException.java │ ├── CookieMissingException.java │ ├── HeaderMissingException.java │ ├── HeaderValidateException.java │ ├── InvalidMediaTypeException.java │ ├── InvalidMimeTypeException.java │ ├── MaxUploadSizeExceededException.java │ ├── MethodNotSupportException.java │ ├── MultipartException.java │ ├── NotFoundException.java │ ├── ParamMissingException.java │ ├── ParamValidateException.java │ ├── PathMissingException.java │ └── ServerInternalException.java │ ├── framework │ ├── ETag.java │ ├── ExceptionResolver.java │ ├── HandlerInterceptor.java │ ├── LastModified.java │ ├── MessageConverter.java │ ├── ModifiedInterceptor.java │ ├── body │ │ ├── FileBody.java │ │ ├── JsonBody.java │ │ ├── StreamBody.java │ │ └── StringBody.java │ ├── handler │ │ ├── HandlerAdapter.java │ │ ├── MappingAdapter.java │ │ ├── MappingHandler.java │ │ ├── MethodHandler.java │ │ └── RequestHandler.java │ ├── view │ │ ├── BodyView.java │ │ ├── ObjectView.java │ │ ├── View.java │ │ └── ViewResolver.java │ └── website │ │ ├── AssetsWebsite.java │ │ ├── BasicWebsite.java │ │ ├── FileBrowser.java │ │ ├── StorageWebsite.java │ │ └── Website.java │ ├── http │ ├── HttpContext.java │ ├── HttpMethod.java │ ├── HttpRequest.java │ ├── HttpResponse.java │ ├── Modified.java │ ├── RequestBody.java │ ├── RequestDispatcher.java │ ├── RequestWrapper.java │ ├── ResponseBody.java │ ├── ResponseWrapper.java │ ├── StandardContext.java │ ├── StandardRequest.java │ ├── StandardResponse.java │ ├── Uri.java │ ├── cookie │ │ ├── Cookie.java │ │ ├── CookieProcessor.java │ │ └── StandardCookieProcessor.java │ ├── multipart │ │ ├── BodyContext.java │ │ ├── MultipartFile.java │ │ ├── MultipartRequest.java │ │ ├── MultipartResolver.java │ │ ├── StandardMultipartFile.java │ │ ├── StandardMultipartRequest.java │ │ └── StandardMultipartResolver.java │ └── session │ │ ├── IdGenerator.java │ │ ├── Session.java │ │ ├── SessionManager.java │ │ ├── StandardIdGenerator.java │ │ ├── StandardSession.java │ │ ├── StandardSessionManager.java │ │ ├── StandardStore.java │ │ └── Store.java │ ├── mapping │ ├── Addition.java │ ├── Mapping.java │ ├── Method.java │ ├── Mime.java │ ├── Pair.java │ ├── Path.java │ ├── UnmodifiableAddition.java │ ├── UnmodifiableMapping.java │ ├── UnmodifiableMethod.java │ ├── UnmodifiableMime.java │ ├── UnmodifiablePair.java │ └── UnmodifiablePath.java │ ├── register │ ├── OnRegister.java │ └── Register.java │ └── util │ ├── AcceptLanguage.java │ ├── Assert.java │ ├── CollectionUtils.java │ ├── DigestUtils.java │ ├── Executors.java │ ├── HttpDateFormat.java │ ├── HttpHeaders.java │ ├── IOUtils.java │ ├── LinkedCaseInsensitiveMap.java │ ├── LinkedMultiValueMap.java │ ├── MediaType.java │ ├── MimeType.java │ ├── MultiValueMap.java │ ├── ObjectUtils.java │ ├── Patterns.java │ ├── StatusCode.java │ ├── StringUtils.java │ ├── TypeWrapper.java │ ├── UrlCoder.java │ └── comparator │ ├── CompoundComparator.java │ └── InvertibleComparator.java ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── tensun │ │ └── andserver │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── assets │ │ └── web │ │ │ ├── css │ │ │ └── login.css │ │ │ ├── image │ │ │ └── logo.png │ │ │ ├── index.html │ │ │ └── login.html │ ├── java │ │ └── com │ │ │ └── tensun │ │ │ └── andserver │ │ │ └── sample │ │ │ ├── App.java │ │ │ ├── CoreService.java │ │ │ ├── MainActivity.java │ │ │ ├── ServerManager.java │ │ │ ├── component │ │ │ ├── AppExceptionResolver.java │ │ │ ├── AppMessageConverter.java │ │ │ ├── InternalWebsite.java │ │ │ ├── LoggerInterceptor.java │ │ │ └── LoginInterceptor.java │ │ │ ├── controller │ │ │ ├── PageController.java │ │ │ └── TestController.java │ │ │ ├── model │ │ │ ├── ReturnData.java │ │ │ └── UserInfo.java │ │ │ └── util │ │ │ ├── FileUtils.java │ │ │ ├── JsonUtils.java │ │ │ ├── Logger.java │ │ │ └── NetUtils.java │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── tensun │ └── andserver │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /.idea/dictionaries/gangan.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 教程 2 | 简书:[使用Android搭建web服务器](https://www.jianshu.com/p/a137ddc3e0da) 3 | 4 | 个人技术博客:[使用Android搭建web服务器](https://hwx95.github.io/2019/03/11/%E4%BD%BF%E7%94%A8Android%E6%90%AD%E5%BB%BAweb%E6%9C%8D%E5%8A%A1%E5%99%A8/) -------------------------------------------------------------------------------- /api/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /api/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 26 5 | buildToolsVersion "26.0.2" 6 | 7 | defaultConfig { 8 | minSdkVersion 17 9 | targetSdkVersion 26 10 | consumerProguardFiles 'proguard-rules.txt' 11 | } 12 | } 13 | 14 | dependencies { 15 | api 'com.yanzhenjie.andserver:annotation:2.0.4' 16 | 17 | implementation "com.yanzhenjie.apache:httpcore:4.4.10" 18 | implementation "com.yanzhenjie.apache:fileupload:1.4" 19 | compileOnly 'com.android.support:support-annotations:27.1.1' 20 | } -------------------------------------------------------------------------------- /api/proguard-rules.txt: -------------------------------------------------------------------------------- 1 | -keep class * implements com.yanzhenjie.andserver.register.OnRegister -------------------------------------------------------------------------------- /api/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 20 | 21 | 22 | 26 | 27 | -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/AndServer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver; 17 | 18 | import android.annotation.SuppressLint; 19 | import android.content.Context; 20 | import android.content.pm.ApplicationInfo; 21 | import android.support.annotation.NonNull; 22 | 23 | import com.yanzhenjie.andserver.util.Assert; 24 | 25 | /** 26 | * Created by YanZhenjie on 2018/6/9. 27 | */ 28 | public class AndServer { 29 | 30 | public static final String TAG = "AndServer"; 31 | 32 | @SuppressLint("StaticFieldLeak") 33 | private static Context sContext; 34 | private static boolean sDebug; 35 | 36 | static void initialize(@NonNull Context context) { 37 | Assert.notNull(context, "The context must not be null."); 38 | 39 | if (sContext == null) { 40 | synchronized (AndServer.class) { 41 | if (sContext == null) { 42 | sContext = context.getApplicationContext(); 43 | ApplicationInfo appInfo = context.getApplicationInfo(); 44 | sDebug = (appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; 45 | } 46 | } 47 | } 48 | } 49 | 50 | /** 51 | * Get the context of the current application. 52 | * 53 | * @return {@link Context}. 54 | */ 55 | @NonNull 56 | public static Context getContext() { 57 | return sContext; 58 | } 59 | 60 | /** 61 | * Whether the application is in debug mode. 62 | * 63 | * @return true, otherwise is false. 64 | */ 65 | public static boolean isDebug() { 66 | return sDebug; 67 | } 68 | 69 | /** 70 | * Create a Builder of Server. 71 | * 72 | * @return {@link Server.Builder}. 73 | */ 74 | @NonNull 75 | public static Server.Builder serverBuilder() { 76 | return Server.newBuilder(); 77 | } 78 | 79 | /** 80 | * Create a Builder of Server. 81 | * 82 | * @param group group name. 83 | * 84 | * @return {@link Server.Builder}. 85 | */ 86 | @NonNull 87 | public static Server.Builder serverBuilder(@NonNull String group) { 88 | return Server.newBuilder(group); 89 | } 90 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/Initialization.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 YanZhenjie. 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 | package com.yanzhenjie.andserver; 17 | 18 | import android.content.ContentProvider; 19 | import android.content.ContentValues; 20 | import android.database.Cursor; 21 | import android.net.Uri; 22 | import android.support.annotation.NonNull; 23 | import android.support.annotation.Nullable; 24 | 25 | /** 26 | * Created by YanZhenjie on 2018/8/29. 27 | */ 28 | public class Initialization extends ContentProvider { 29 | 30 | @Override 31 | public boolean onCreate() { 32 | AndServer.initialize(getContext()); 33 | return false; 34 | } 35 | 36 | @Nullable 37 | @Override 38 | public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, 39 | @Nullable String[] selectionArgs, @Nullable String sortOrder) { 40 | return null; 41 | } 42 | 43 | @Nullable 44 | @Override 45 | public String getType(@NonNull Uri uri) { 46 | return null; 47 | } 48 | 49 | @Nullable 50 | @Override 51 | public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) { 52 | return null; 53 | } 54 | 55 | @Override 56 | public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) { 57 | return 0; 58 | } 59 | 60 | @Override 61 | public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, 62 | @Nullable String[] selectionArgs) { 63 | return 0; 64 | } 65 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/SSLInitializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 YanZhenjie. 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 | package com.yanzhenjie.andserver; 17 | 18 | import android.support.annotation.NonNull; 19 | 20 | import javax.net.ssl.SSLException; 21 | import javax.net.ssl.SSLServerSocket; 22 | 23 | /** 24 | * Created by YanZhenjie on 2018/9/10. 25 | */ 26 | public interface SSLInitializer { 27 | 28 | void onCreated(@NonNull SSLServerSocket socket) throws SSLException; 29 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/error/BasicException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.error; 17 | 18 | /** 19 | * Created by YanZhenjie on 2018/7/19. 20 | */ 21 | public class BasicException extends RuntimeException { 22 | 23 | /** 24 | * Status code. 25 | */ 26 | private int mStatusCode; 27 | 28 | public BasicException(int statusCode, String message) { 29 | super(message); 30 | this.mStatusCode = statusCode; 31 | } 32 | 33 | public BasicException(int statusCode, String message, Throwable cause) { 34 | super(message, cause); 35 | this.mStatusCode = statusCode; 36 | } 37 | 38 | public BasicException(int statusCode, Throwable cause) { 39 | super(cause); 40 | this.mStatusCode = statusCode; 41 | } 42 | 43 | public int getStatusCode() { 44 | return mStatusCode; 45 | } 46 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/error/BodyMissingException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.error; 17 | 18 | import com.yanzhenjie.andserver.util.StatusCode; 19 | 20 | /** 21 | * Created by YanZhenjie on 2018/9/10. 22 | */ 23 | public class BodyMissingException extends BasicException { 24 | 25 | private static final String MESSAGE = "RequestBody is missing."; 26 | 27 | public BodyMissingException() { 28 | super(StatusCode.SC_BAD_REQUEST, MESSAGE); 29 | } 30 | 31 | public BodyMissingException(Throwable cause) { 32 | super(StatusCode.SC_BAD_REQUEST, MESSAGE, cause); 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/error/ContentNotAcceptableException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.error; 17 | 18 | import com.yanzhenjie.andserver.util.StatusCode; 19 | 20 | /** 21 | * Created by YanZhenjie on 2018/9/8. 22 | */ 23 | public class ContentNotAcceptableException extends BasicException { 24 | 25 | private static final String MESSAGE = "Could not find acceptable representation."; 26 | 27 | public ContentNotAcceptableException() { 28 | super(StatusCode.SC_NOT_ACCEPTABLE, MESSAGE); 29 | } 30 | 31 | public ContentNotAcceptableException(String message, Throwable cause) { 32 | super(StatusCode.SC_NOT_ACCEPTABLE, message, cause); 33 | } 34 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/error/ContentNotSupportedException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.error; 17 | 18 | import com.yanzhenjie.andserver.util.MediaType; 19 | import com.yanzhenjie.andserver.util.StatusCode; 20 | 21 | /** 22 | * Created by YanZhenjie on 2018/9/8. 23 | */ 24 | public class ContentNotSupportedException extends BasicException { 25 | 26 | private static final String MESSAGE = "The content type [%s] is not supported."; 27 | 28 | public ContentNotSupportedException(MediaType mediaType) { 29 | super(StatusCode.SC_UNSUPPORTED_MEDIA_TYPE, String.format(MESSAGE, mediaType)); 30 | } 31 | 32 | public ContentNotSupportedException(MediaType mediaType, Throwable cause) { 33 | super(StatusCode.SC_UNSUPPORTED_MEDIA_TYPE, String.format(MESSAGE, mediaType), cause); 34 | } 35 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/error/CookieMissingException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.error; 17 | 18 | import com.yanzhenjie.andserver.util.StatusCode; 19 | 20 | /** 21 | * Created by YanZhenjie on 2018/9/9. 22 | */ 23 | public class CookieMissingException extends BasicException { 24 | 25 | private static final String MESSAGE = "Missing cookie [%s] for method parameter."; 26 | 27 | public CookieMissingException(String name) { 28 | super(StatusCode.SC_BAD_REQUEST, String.format(MESSAGE, name)); 29 | } 30 | 31 | public CookieMissingException(String name, Throwable cause) { 32 | super(StatusCode.SC_BAD_REQUEST, String.format(MESSAGE, name), cause); 33 | } 34 | 35 | public CookieMissingException(Throwable cause) { 36 | super(StatusCode.SC_BAD_REQUEST, String.format(MESSAGE, ""), cause); 37 | } 38 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/error/HeaderMissingException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.error; 17 | 18 | import com.yanzhenjie.andserver.util.StatusCode; 19 | 20 | /** 21 | * Created by YanZhenjie on 2018/9/9. 22 | */ 23 | public class HeaderMissingException extends BasicException { 24 | 25 | private static final String MESSAGE = "Missing header [%s] for method parameter."; 26 | 27 | public HeaderMissingException(String name) { 28 | super(StatusCode.SC_BAD_REQUEST, String.format(MESSAGE, name)); 29 | } 30 | 31 | public HeaderMissingException(String name, Throwable cause) { 32 | super(StatusCode.SC_BAD_REQUEST, String.format(MESSAGE, name), cause); 33 | } 34 | 35 | public HeaderMissingException(Throwable cause) { 36 | super(StatusCode.SC_BAD_REQUEST, String.format(MESSAGE, ""), cause); 37 | } 38 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/error/HeaderValidateException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.error; 17 | 18 | import com.yanzhenjie.andserver.util.StatusCode; 19 | 20 | /** 21 | * Created by YanZhenjie on 2018/9/9. 22 | */ 23 | public class HeaderValidateException extends BasicException { 24 | 25 | public HeaderValidateException(String message) { 26 | super(StatusCode.SC_FORBIDDEN, message); 27 | } 28 | 29 | public HeaderValidateException(String message, Throwable cause) { 30 | super(StatusCode.SC_FORBIDDEN, message, cause); 31 | } 32 | 33 | public HeaderValidateException(Throwable cause) { 34 | super(StatusCode.SC_FORBIDDEN, cause); 35 | } 36 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/error/InvalidMediaTypeException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.error; 17 | 18 | /** 19 | * Created by YanZhenjie on 2018/7/10. 20 | */ 21 | public class InvalidMediaTypeException extends IllegalArgumentException { 22 | 23 | private String mMediaType; 24 | 25 | /** 26 | * Create a new InvalidMediaTypeException for the given media type. 27 | * 28 | * @param mediaType the offending media type. 29 | * @param message a detail message indicating the invalid part. 30 | */ 31 | public InvalidMediaTypeException(String mediaType, String message) { 32 | super("Invalid media type \"" + mediaType + "\": " + message); 33 | this.mMediaType = mediaType; 34 | } 35 | 36 | /** 37 | * Constructor that allows wrapping {@link InvalidMimeTypeException}. 38 | */ 39 | public InvalidMediaTypeException(InvalidMimeTypeException ex) { 40 | super(ex.getMessage(), ex); 41 | this.mMediaType = ex.getMimeType(); 42 | } 43 | 44 | /** 45 | * Return the offending media type. 46 | */ 47 | public String getMediaType() { 48 | return this.mMediaType; 49 | } 50 | 51 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/error/InvalidMimeTypeException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.error; 17 | 18 | /** 19 | * Created by YanZhenjie on 2018/7/10. 20 | */ 21 | public class InvalidMimeTypeException extends IllegalArgumentException { 22 | 23 | private final String mMimeType; 24 | 25 | /** 26 | * Create a new InvalidContentTypeException for the given content type. 27 | * 28 | * @param mimeType the offending media type. 29 | * @param message a detail message indicating the invalid part. 30 | */ 31 | public InvalidMimeTypeException(String mimeType, String message) { 32 | super("Invalid mime type \"" + mimeType + "\": " + message); 33 | this.mMimeType = mimeType; 34 | } 35 | 36 | /** 37 | * Return the offending content type. 38 | */ 39 | public String getMimeType() { 40 | return this.mMimeType; 41 | } 42 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/error/MaxUploadSizeExceededException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.error; 17 | 18 | import com.yanzhenjie.andserver.util.StatusCode; 19 | 20 | /** 21 | * Created by YanZhenjie on 2018/8/9. 22 | */ 23 | public class MaxUploadSizeExceededException extends BasicException { 24 | 25 | private final long mMaxSize; 26 | 27 | /** 28 | * Constructor for MaxUploadSizeExceededException. 29 | * 30 | * @param maxUploadSize the maximum upload size allowed. 31 | */ 32 | public MaxUploadSizeExceededException(long maxUploadSize) { 33 | this(maxUploadSize, null); 34 | } 35 | 36 | /** 37 | * Constructor for MaxUploadSizeExceededException. 38 | * 39 | * @param maxSize the maximum upload size allowed. 40 | * @param ex root cause from multipart parsing API in use. 41 | */ 42 | public MaxUploadSizeExceededException(long maxSize, Throwable ex) { 43 | super(StatusCode.SC_REQUEST_ENTITY_TOO_LARGE, "Maximum upload size of " + maxSize + " bytes exceeded", ex); 44 | this.mMaxSize = maxSize; 45 | } 46 | 47 | /** 48 | * Return the maximum upload size allowed. 49 | */ 50 | public long getMaxSize() { 51 | return this.mMaxSize; 52 | } 53 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/error/MethodNotSupportException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.error; 17 | 18 | import com.yanzhenjie.andserver.http.HttpMethod; 19 | import com.yanzhenjie.andserver.util.StatusCode; 20 | 21 | /** 22 | * Created by YanZhenjie on 2018/7/19. 23 | */ 24 | public class MethodNotSupportException extends BasicException { 25 | 26 | private static final String MESSAGE = "The request method [%s] is not supported."; 27 | 28 | public MethodNotSupportException(HttpMethod method) { 29 | super(StatusCode.SC_METHOD_NOT_ALLOWED, String.format(MESSAGE, method.value())); 30 | } 31 | 32 | public MethodNotSupportException(HttpMethod method, Throwable cause) { 33 | super(StatusCode.SC_METHOD_NOT_ALLOWED, String.format(MESSAGE, method.value()), cause); 34 | } 35 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/error/MultipartException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.error; 17 | 18 | import com.yanzhenjie.andserver.util.StatusCode; 19 | 20 | /** 21 | * Created by YanZhenjie on 2018/8/9. 22 | */ 23 | public class MultipartException extends BasicException { 24 | 25 | /** 26 | * Constructor for MultipartException. 27 | * 28 | * @param msg the detail message. 29 | */ 30 | public MultipartException(String msg) { 31 | super(StatusCode.SC_BAD_REQUEST, msg); 32 | } 33 | 34 | /** 35 | * Constructor for MultipartException. 36 | * 37 | * @param msg the detail message 38 | * @param cause the root cause from the multipart parsing API in use 39 | */ 40 | public MultipartException(String msg, Throwable cause) { 41 | super(StatusCode.SC_BAD_REQUEST, msg, cause); 42 | } 43 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/error/NotFoundException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.error; 17 | 18 | import com.yanzhenjie.andserver.util.StatusCode; 19 | 20 | /** 21 | * Created by YanZhenjie on 2018/7/19. 22 | */ 23 | public class NotFoundException extends BasicException { 24 | 25 | private static final String MESSAGE = "The resource [%s] is not found."; 26 | 27 | public NotFoundException() { 28 | super(StatusCode.SC_NOT_FOUND, String.format(MESSAGE, "")); 29 | } 30 | 31 | public NotFoundException(String path) { 32 | super(StatusCode.SC_NOT_FOUND, String.format(MESSAGE, path)); 33 | } 34 | 35 | public NotFoundException(String path, Throwable cause) { 36 | super(StatusCode.SC_NOT_FOUND, String.format(MESSAGE, path), cause); 37 | } 38 | 39 | public NotFoundException(Throwable cause) { 40 | super(StatusCode.SC_NOT_FOUND, String.format(MESSAGE, ""), cause); 41 | } 42 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/error/ParamMissingException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.error; 17 | 18 | import com.yanzhenjie.andserver.util.StatusCode; 19 | 20 | /** 21 | * Created by YanZhenjie on 2018/9/9. 22 | */ 23 | public class ParamMissingException extends BasicException { 24 | 25 | private static final String MESSAGE = "Missing param [%s] for method parameter."; 26 | 27 | public ParamMissingException(String name) { 28 | super(StatusCode.SC_BAD_REQUEST, String.format(MESSAGE, name)); 29 | } 30 | 31 | public ParamMissingException(String name, Throwable cause) { 32 | super(StatusCode.SC_BAD_REQUEST, String.format(MESSAGE, name), cause); 33 | } 34 | 35 | public ParamMissingException(Throwable cause) { 36 | super(StatusCode.SC_BAD_REQUEST, String.format(MESSAGE, ""), cause); 37 | } 38 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/error/ParamValidateException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.error; 17 | 18 | import com.yanzhenjie.andserver.util.StatusCode; 19 | 20 | /** 21 | * Created by YanZhenjie on 2018/9/8. 22 | */ 23 | public class ParamValidateException extends BasicException { 24 | 25 | public ParamValidateException(String message) { 26 | super(StatusCode.SC_FORBIDDEN, message); 27 | } 28 | 29 | public ParamValidateException(String message, Throwable cause) { 30 | super(StatusCode.SC_FORBIDDEN, message, cause); 31 | } 32 | 33 | public ParamValidateException(Throwable cause) { 34 | super(StatusCode.SC_FORBIDDEN, cause); 35 | } 36 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/error/PathMissingException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.error; 17 | 18 | import com.yanzhenjie.andserver.util.StatusCode; 19 | 20 | /** 21 | * Created by YanZhenjie on 2018/9/10. 22 | */ 23 | public class PathMissingException extends BasicException { 24 | 25 | private static final String MESSAGE = "Missing param [%s] for path parameter."; 26 | 27 | public PathMissingException(String name) { 28 | super(StatusCode.SC_BAD_REQUEST, String.format(MESSAGE, name)); 29 | } 30 | 31 | public PathMissingException(String name, Throwable cause) { 32 | super(StatusCode.SC_BAD_REQUEST, String.format(MESSAGE, name), cause); 33 | } 34 | 35 | public PathMissingException(Throwable cause) { 36 | super(StatusCode.SC_BAD_REQUEST, String.format(MESSAGE, ""), cause); 37 | } 38 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/error/ServerInternalException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 YanZhenjie. 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 | package com.yanzhenjie.andserver.error; 17 | 18 | import com.yanzhenjie.andserver.util.StatusCode; 19 | 20 | /** 21 | * Created by YanZhenjie on 2018/9/4. 22 | */ 23 | public class ServerInternalException extends BasicException { 24 | 25 | private static final String MESSAGE = "Server internal error"; 26 | 27 | public ServerInternalException(String subMessage) { 28 | super(StatusCode.SC_INTERNAL_SERVER_ERROR, String.format("%s, %s.", MESSAGE, subMessage)); 29 | } 30 | 31 | public ServerInternalException(String subMessage, Throwable cause) { 32 | super(StatusCode.SC_INTERNAL_SERVER_ERROR, String.format("%s, %s.", MESSAGE, subMessage), cause); 33 | } 34 | 35 | public ServerInternalException(Throwable cause) { 36 | super(StatusCode.SC_INTERNAL_SERVER_ERROR, String.format("%s.", MESSAGE), cause); 37 | } 38 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/framework/ETag.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 YanZhenjie. 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 | package com.yanzhenjie.andserver.framework; 17 | 18 | import android.support.annotation.NonNull; 19 | 20 | import com.yanzhenjie.andserver.http.HttpRequest; 21 | 22 | import java.io.IOException; 23 | 24 | /** 25 | * Created by YanZhenjie on 2018/8/31. 26 | */ 27 | public interface ETag { 28 | 29 | /** 30 | * Get the {@code ETag} requesting the specified resource. 31 | * 32 | *

Can simply return {@code null} if there's no support. 33 | */ 34 | String getETag(@NonNull HttpRequest request) throws IOException; 35 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/framework/ExceptionResolver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.framework; 17 | 18 | import android.support.annotation.NonNull; 19 | 20 | import com.yanzhenjie.andserver.error.BasicException; 21 | import com.yanzhenjie.andserver.http.HttpRequest; 22 | import com.yanzhenjie.andserver.http.HttpResponse; 23 | import com.yanzhenjie.andserver.framework.body.StringBody; 24 | import com.yanzhenjie.andserver.util.StatusCode; 25 | 26 | /** 27 | * Created by YanZhenjie on 2018/8/8. 28 | */ 29 | public interface ExceptionResolver { 30 | 31 | ExceptionResolver DEFAULT = new ExceptionResolver() { 32 | @Override 33 | public void onResolve(@NonNull HttpRequest request, @NonNull HttpResponse response, @NonNull Throwable e) { 34 | if (e instanceof BasicException) { 35 | BasicException ex = (BasicException)e; 36 | response.setStatus(ex.getStatusCode()); 37 | } else { 38 | response.setStatus(StatusCode.SC_INTERNAL_SERVER_ERROR); 39 | } 40 | response.setBody(new StringBody(e.getMessage())); 41 | } 42 | }; 43 | 44 | /** 45 | * Resolve exceptions that occur in the program, replacing the default output information for the exception. 46 | * 47 | * @param request current request. 48 | * @param response current response. 49 | * @param e an exception occurred in the program. 50 | */ 51 | void onResolve(@NonNull HttpRequest request, @NonNull HttpResponse response, @NonNull Throwable e); 52 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/framework/HandlerInterceptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.framework; 17 | 18 | import android.support.annotation.NonNull; 19 | 20 | import com.yanzhenjie.andserver.framework.handler.RequestHandler; 21 | import com.yanzhenjie.andserver.http.HttpRequest; 22 | import com.yanzhenjie.andserver.http.HttpResponse; 23 | 24 | /** 25 | * Created by YanZhenjie on 2018/8/8. 26 | */ 27 | public interface HandlerInterceptor { 28 | 29 | /** 30 | * Intercept the execution of a handler. 31 | * 32 | * @param request current request. 33 | * @param response current response. 34 | * @param handler the corresponding handler of the current request. 35 | * 36 | * @return true if the interceptor has processed the request and responded. 37 | */ 38 | boolean onIntercept(@NonNull HttpRequest request, @NonNull HttpResponse response, @NonNull RequestHandler handler) 39 | throws Exception; 40 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/framework/LastModified.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 YanZhenjie. 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 | package com.yanzhenjie.andserver.framework; 17 | 18 | import android.support.annotation.NonNull; 19 | 20 | import com.yanzhenjie.andserver.http.HttpRequest; 21 | 22 | import java.io.IOException; 23 | 24 | /** 25 | * Created by YanZhenjie on 2018/8/29. 26 | */ 27 | public interface LastModified { 28 | 29 | /** 30 | * The return value will be sent to the HTTP client as {@code Last-Modified} header, and compared with {@code 31 | * If-Modified-Since} headers that the client sends back. The content will only get regenerated if there has been a 32 | * modification. 33 | * 34 | * @param request current request 35 | * 36 | * @return the time the underlying resource was last modified, or -1 meaning that the content must always be 37 | * regenerated. 38 | */ 39 | long getLastModified(@NonNull HttpRequest request) throws IOException; 40 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/framework/MessageConverter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 YanZhenjie. 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 | package com.yanzhenjie.andserver.framework; 17 | 18 | import android.support.annotation.NonNull; 19 | import android.support.annotation.Nullable; 20 | 21 | import com.yanzhenjie.andserver.framework.view.ViewResolver; 22 | import com.yanzhenjie.andserver.http.ResponseBody; 23 | import com.yanzhenjie.andserver.util.MediaType; 24 | 25 | import java.io.IOException; 26 | import java.io.InputStream; 27 | import java.lang.reflect.Type; 28 | 29 | /** 30 | * Created by YanZhenjie on 2018/9/6. 31 | */ 32 | public interface MessageConverter { 33 | 34 | /** 35 | * Convert a specific output to the response body. Some of the return values of handlers that cannot be recognized 36 | * by {@link ViewResolver} require a message converter to be converted to a response body. 37 | * 38 | * @param output output of handle. 39 | * @param mediaType the content media type specified by the handler. 40 | */ 41 | ResponseBody convert(@NonNull Object output, @Nullable MediaType mediaType); 42 | 43 | /** 44 | * Convert RequestBody to a object. 45 | * 46 | * @param stream {@link InputStream}. 47 | * @param mediaType he content media type. 48 | * @param type type of object. 49 | * @param type of object. 50 | * 51 | * @return object. 52 | */ 53 | @Nullable 54 | T convert(@NonNull InputStream stream, @Nullable MediaType mediaType, Type type) throws IOException; 55 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/framework/ModifiedInterceptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.framework; 17 | 18 | import android.support.annotation.NonNull; 19 | import android.util.Log; 20 | 21 | import com.yanzhenjie.andserver.AndServer; 22 | import com.yanzhenjie.andserver.framework.handler.RequestHandler; 23 | import com.yanzhenjie.andserver.http.HttpMethod; 24 | import com.yanzhenjie.andserver.http.HttpRequest; 25 | import com.yanzhenjie.andserver.http.HttpResponse; 26 | import com.yanzhenjie.andserver.http.Modified; 27 | 28 | import java.io.IOException; 29 | 30 | /** 31 | * Created by YanZhenjie on 2018/9/14. 32 | */ 33 | public class ModifiedInterceptor implements HandlerInterceptor { 34 | 35 | @Override 36 | public boolean onIntercept(@NonNull HttpRequest request, @NonNull HttpResponse response, 37 | @NonNull RequestHandler handler) throws Exception { 38 | // Process cache header, if supported by the handler. 39 | HttpMethod method = request.getMethod(); 40 | if (method == HttpMethod.GET || method == HttpMethod.HEAD) { 41 | String eTag = null; 42 | try { 43 | eTag = handler.getETag(request); 44 | } catch (IOException ignored) { 45 | Log.w(AndServer.TAG, ignored.getMessage()); 46 | } 47 | long lastModified = -1; 48 | try { 49 | lastModified = handler.getLastModified(request); 50 | } catch (IOException ignored) { 51 | Log.w(AndServer.TAG, ignored.getMessage()); 52 | } 53 | return new Modified(request, response).process(eTag, lastModified); 54 | } 55 | return false; 56 | } 57 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/framework/body/FileBody.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.framework.body; 17 | 18 | import android.support.annotation.NonNull; 19 | import android.support.annotation.Nullable; 20 | 21 | import com.yanzhenjie.andserver.http.ResponseBody; 22 | import com.yanzhenjie.andserver.util.IOUtils; 23 | import com.yanzhenjie.andserver.util.MediaType; 24 | 25 | import java.io.File; 26 | import java.io.FileInputStream; 27 | import java.io.IOException; 28 | import java.io.OutputStream; 29 | 30 | /** 31 | * Created by YanZhenjie on 2018/8/6. 32 | */ 33 | public class FileBody implements ResponseBody { 34 | 35 | private File mBody; 36 | 37 | public FileBody(File body) { 38 | if (body == null) { 39 | throw new IllegalArgumentException("The file cannot be null."); 40 | } 41 | this.mBody = body; 42 | } 43 | 44 | @Override 45 | public long contentLength() { 46 | return mBody.length(); 47 | } 48 | 49 | @Nullable 50 | @Override 51 | public MediaType contentType() { 52 | return MediaType.getFileMediaType(mBody.getName()); 53 | } 54 | 55 | @Override 56 | public void writeTo(@NonNull OutputStream output) throws IOException { 57 | IOUtils.write(new FileInputStream(mBody), output); 58 | } 59 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/framework/body/JsonBody.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.framework.body; 17 | 18 | import android.support.annotation.Nullable; 19 | 20 | import com.yanzhenjie.andserver.util.MediaType; 21 | 22 | import org.json.JSONObject; 23 | 24 | /** 25 | * Created by YanZhenjie on 2018/8/8. 26 | */ 27 | public class JsonBody extends StringBody { 28 | 29 | public JsonBody(String body) { 30 | super(body); 31 | } 32 | 33 | public JsonBody(JSONObject object) { 34 | super(object.toString()); 35 | } 36 | 37 | @Nullable 38 | @Override 39 | public MediaType contentType() { 40 | return MediaType.APPLICATION_JSON_UTF8; 41 | } 42 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/framework/body/StreamBody.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 YanZhenjie. 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 | package com.yanzhenjie.andserver.framework.body; 17 | 18 | import android.support.annotation.NonNull; 19 | import android.support.annotation.Nullable; 20 | 21 | import com.yanzhenjie.andserver.http.ResponseBody; 22 | import com.yanzhenjie.andserver.util.IOUtils; 23 | import com.yanzhenjie.andserver.util.MediaType; 24 | 25 | import java.io.IOException; 26 | import java.io.InputStream; 27 | import java.io.OutputStream; 28 | 29 | /** 30 | * Created by YanZhenjie on 2018/9/7. 31 | */ 32 | public class StreamBody implements ResponseBody { 33 | 34 | private InputStream mStream; 35 | private long mLength; 36 | private MediaType mMediaType; 37 | 38 | public StreamBody(InputStream stream) { 39 | this(stream, MediaType.APPLICATION_OCTET_STREAM); 40 | } 41 | 42 | public StreamBody(InputStream stream, long length) { 43 | this(stream, length, MediaType.APPLICATION_OCTET_STREAM); 44 | } 45 | 46 | public StreamBody(InputStream stream, MediaType mediaType) { 47 | this(stream, 0, mediaType); 48 | } 49 | 50 | public StreamBody(InputStream stream, long length, MediaType mediaType) { 51 | this.mStream = stream; 52 | this.mLength = length; 53 | this.mMediaType = mediaType; 54 | } 55 | 56 | @Override 57 | public long contentLength() { 58 | return mLength; 59 | } 60 | 61 | @Nullable 62 | @Override 63 | public MediaType contentType() { 64 | return mMediaType; 65 | } 66 | 67 | @Override 68 | public void writeTo(@NonNull OutputStream output) throws IOException { 69 | IOUtils.write(mStream, output); 70 | } 71 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/framework/body/StringBody.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.framework.body; 17 | 18 | import android.support.annotation.NonNull; 19 | import android.support.annotation.Nullable; 20 | 21 | import com.yanzhenjie.andserver.http.ResponseBody; 22 | import com.yanzhenjie.andserver.util.IOUtils; 23 | import com.yanzhenjie.andserver.util.MediaType; 24 | import com.yanzhenjie.andserver.util.StringUtils; 25 | 26 | import org.apache.commons.io.Charsets; 27 | 28 | import java.io.IOException; 29 | import java.io.OutputStream; 30 | import java.nio.charset.Charset; 31 | 32 | /** 33 | * Created by YanZhenjie on 2018/8/6. 34 | */ 35 | public class StringBody implements ResponseBody { 36 | 37 | private byte[] mBody; 38 | private MediaType mMediaType; 39 | 40 | public StringBody(String body) { 41 | this(body, MediaType.TEXT_PLAIN); 42 | } 43 | 44 | public StringBody(String body, MediaType mediaType) { 45 | if (StringUtils.isEmpty(body)) { 46 | throw new IllegalArgumentException("The content cannot be null or empty."); 47 | } 48 | 49 | this.mMediaType = mediaType; 50 | if (mMediaType == null) { 51 | mMediaType = new MediaType(MediaType.TEXT_PLAIN, Charsets.UTF_8); 52 | } 53 | 54 | Charset charset = mMediaType.getCharset(); 55 | if (charset == null) charset = Charset.forName("UTF-8"); 56 | this.mBody = body.getBytes(charset); 57 | } 58 | 59 | @Override 60 | public long contentLength() { 61 | return mBody.length; 62 | } 63 | 64 | @Nullable 65 | @Override 66 | public MediaType contentType() { 67 | Charset charset = mMediaType.getCharset(); 68 | if (charset == null) { 69 | charset = Charsets.UTF_8; 70 | return new MediaType(mMediaType.getType(), mMediaType.getSubtype(), charset); 71 | } 72 | return mMediaType; 73 | } 74 | 75 | @Override 76 | public void writeTo(@NonNull OutputStream output) throws IOException { 77 | IOUtils.write(output, mBody); 78 | } 79 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/framework/handler/HandlerAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 YanZhenjie. 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 | package com.yanzhenjie.andserver.framework.handler; 17 | 18 | import android.support.annotation.NonNull; 19 | import android.support.annotation.Nullable; 20 | 21 | import com.yanzhenjie.andserver.error.NotFoundException; 22 | import com.yanzhenjie.andserver.http.HttpRequest; 23 | 24 | /** 25 | * Created by YanZhenjie on 2018/9/4. 26 | */ 27 | public interface HandlerAdapter { 28 | 29 | /** 30 | * Whether to intercept the current request. 31 | * 32 | * @param request current request. 33 | * 34 | * @return returns true, otherwise false. 35 | */ 36 | boolean intercept(@NonNull HttpRequest request); 37 | 38 | /** 39 | * Get the handler that handles the current request. 40 | * 41 | * @param request current request. 42 | * 43 | * @return the handler to handle current request. 44 | * 45 | * @throws NotFoundException if current request cannot find the corresponding handler. 46 | */ 47 | @Nullable 48 | RequestHandler getHandler(@NonNull HttpRequest request); 49 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/framework/handler/MethodHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.framework.handler; 17 | 18 | import android.support.annotation.NonNull; 19 | import android.support.annotation.Nullable; 20 | 21 | import com.yanzhenjie.andserver.mapping.Addition; 22 | import com.yanzhenjie.andserver.mapping.Mapping; 23 | 24 | /** 25 | * Created by YanZhenjie on 2018/6/16. 26 | */ 27 | public interface MethodHandler extends RequestHandler { 28 | 29 | /** 30 | * Is a rest style handler ? 31 | * 32 | * @return true, otherwise is false. 33 | */ 34 | boolean isRest(); 35 | 36 | /** 37 | * Get addition configuration, addition provides some added value. 38 | * 39 | * @return {@link Addition}. 40 | */ 41 | @Nullable 42 | Addition getAddition(); 43 | 44 | /** 45 | * Get mapping configuration, mapping provides all the annotation information for this method. 46 | * 47 | * @return {@link Mapping}. 48 | */ 49 | @NonNull 50 | Mapping getMapping(); 51 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/framework/handler/RequestHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 YanZhenjie. 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 | package com.yanzhenjie.andserver.framework.handler; 17 | 18 | import android.support.annotation.NonNull; 19 | import android.support.annotation.Nullable; 20 | 21 | import com.yanzhenjie.andserver.framework.view.View; 22 | import com.yanzhenjie.andserver.http.HttpRequest; 23 | import com.yanzhenjie.andserver.http.HttpResponse; 24 | 25 | import java.io.IOException; 26 | 27 | /** 28 | * Created by YanZhenjie on 2018/8/28. 29 | */ 30 | public interface RequestHandler { 31 | 32 | /** 33 | * Can simply return {@code null} or empty if there's no support in this handler. 34 | * 35 | * @param request current request. 36 | * 37 | * @return the ETag value for this handler. 38 | */ 39 | @Nullable 40 | String getETag(@NonNull HttpRequest request) throws IOException; 41 | 42 | /** 43 | * Can simply return -1 if there's no support in this handler. 44 | * 45 | * @param request current request. 46 | * 47 | * @return the {@code LastModified} value for resource. 48 | */ 49 | long getLastModified(@NonNull HttpRequest request) throws IOException; 50 | 51 | /** 52 | * Use the given handler to handle this request. 53 | * 54 | * @param request current request. 55 | * @param response current response. 56 | * 57 | * @return the impression sent to the client. 58 | */ 59 | View handle(@NonNull HttpRequest request, @NonNull HttpResponse response) throws IOException; 60 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/framework/view/BodyView.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 YanZhenjie. 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 | package com.yanzhenjie.andserver.framework.view; 17 | 18 | import android.support.annotation.NonNull; 19 | import android.support.annotation.Nullable; 20 | 21 | import com.yanzhenjie.andserver.http.ResponseBody; 22 | 23 | /** 24 | * Created by YanZhenjie on 2018/9/7. 25 | */ 26 | public class BodyView implements View { 27 | 28 | private ResponseBody mBody; 29 | 30 | public BodyView(@NonNull ResponseBody body) { 31 | this.mBody = body; 32 | } 33 | 34 | @Override 35 | public boolean rest() { 36 | return true; 37 | } 38 | 39 | @Nullable 40 | @Override 41 | public Object output() { 42 | return mBody; 43 | } 44 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/framework/view/ObjectView.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.framework.view; 17 | 18 | import android.support.annotation.Nullable; 19 | 20 | /** 21 | * Created by YanZhenjie on 2018/9/9. 22 | */ 23 | public class ObjectView implements View { 24 | 25 | private final boolean isRest; 26 | private final Object output; 27 | 28 | public ObjectView(boolean isRest, Object output) { 29 | this.isRest = isRest; 30 | this.output = output; 31 | } 32 | 33 | @Override 34 | public boolean rest() { 35 | return isRest; 36 | } 37 | 38 | @Nullable 39 | @Override 40 | public Object output() { 41 | return output; 42 | } 43 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/framework/view/View.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 YanZhenjie. 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 | package com.yanzhenjie.andserver.framework.view; 17 | 18 | import android.support.annotation.Nullable; 19 | 20 | /** 21 | * Created by YanZhenjie on 2018/8/29. 22 | */ 23 | public interface View { 24 | 25 | /** 26 | * Is it a rest style view? 27 | * 28 | * @return true, otherwise is false. 29 | */ 30 | boolean rest(); 31 | 32 | /** 33 | * Get the output. 34 | * 35 | * @return output, e.g. {@code "redirect:/user/list"}, {@code "forward:/user/list"}, {@code "/user/list"}, String, 36 | * JSONObject, Object, Basic data type(int, short, long, double, float, byte, boolean char). 37 | */ 38 | @Nullable 39 | Object output(); 40 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/framework/website/BasicWebsite.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 YanZhenjie. 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 | package com.yanzhenjie.andserver.framework.website; 17 | 18 | import android.support.annotation.NonNull; 19 | 20 | import com.yanzhenjie.andserver.http.HttpRequest; 21 | import com.yanzhenjie.andserver.util.Assert; 22 | import com.yanzhenjie.andserver.util.StringUtils; 23 | 24 | import java.io.File; 25 | import java.io.IOException; 26 | 27 | /** 28 | * Created by YanZhenjie on 2018/9/6. 29 | */ 30 | public abstract class BasicWebsite extends Website { 31 | 32 | public static final String DEFAULT_INDEX = "index.html"; 33 | 34 | private final String mIndexFileName; 35 | 36 | public BasicWebsite() { 37 | this(DEFAULT_INDEX); 38 | } 39 | 40 | /** 41 | * Create a website object. 42 | * 43 | * @param indexFileName the default file name for each directory, e.g. index.html. 44 | */ 45 | public BasicWebsite(@NonNull String indexFileName) { 46 | Assert.isTrue(!StringUtils.isEmpty(indexFileName), "The indexFileName cannot be empty."); 47 | this.mIndexFileName = indexFileName; 48 | } 49 | 50 | @Override 51 | public String getETag(@NonNull HttpRequest request) throws IOException { 52 | return null; 53 | } 54 | 55 | @Override 56 | public long getLastModified(@NonNull HttpRequest request) throws IOException { 57 | return -1; 58 | } 59 | 60 | /** 61 | * Get the name of the indexFile. 62 | * 63 | * @return file name, does not include the path. 64 | */ 65 | @NonNull 66 | protected final String getIndexFileName() { 67 | return mIndexFileName; 68 | } 69 | 70 | /** 71 | * Add the '/' to the beginning. 72 | * 73 | * @param target target string. 74 | * 75 | * @return rule result. 76 | */ 77 | protected String addStartSlash(@NonNull String target) { 78 | if (!target.startsWith(File.separator)) target = File.separator + target; 79 | return target; 80 | } 81 | 82 | /** 83 | * Add '/' at the ending. 84 | * 85 | * @param target target string. 86 | * 87 | * @return rule result. 88 | */ 89 | protected String addEndSlash(@NonNull String target) { 90 | if (!target.endsWith(File.separator)) target = target + File.separator; 91 | return target; 92 | } 93 | 94 | /** 95 | * Remove '/' at the beginning. 96 | * 97 | * @param target target string. 98 | * 99 | * @return rule result. 100 | */ 101 | protected String trimStartSlash(@NonNull String target) { 102 | while (target.startsWith(File.separator)) target = target.substring(1); 103 | return target; 104 | } 105 | 106 | /** 107 | * Remove '/' at the ending. 108 | * 109 | * @param target target string. 110 | * 111 | * @return rule result. 112 | */ 113 | protected String trimEndSlash(@NonNull String target) { 114 | while (target.endsWith(File.separator)) target = target.substring(0, target.length() - 1); 115 | return target; 116 | } 117 | 118 | /** 119 | * Remove the '/' at the beginning and ending. 120 | * 121 | * @param target target string. 122 | * 123 | * @return rule result. 124 | */ 125 | protected String trimSlash(@NonNull String target) { 126 | target = trimStartSlash(target); 127 | target = trimEndSlash(target); 128 | return target; 129 | } 130 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/framework/website/Website.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 YanZhenjie. 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 | package com.yanzhenjie.andserver.framework.website; 17 | 18 | import android.support.annotation.NonNull; 19 | import android.support.annotation.Nullable; 20 | 21 | import com.yanzhenjie.andserver.framework.ETag; 22 | import com.yanzhenjie.andserver.framework.LastModified; 23 | import com.yanzhenjie.andserver.framework.handler.HandlerAdapter; 24 | import com.yanzhenjie.andserver.framework.handler.RequestHandler; 25 | import com.yanzhenjie.andserver.framework.view.BodyView; 26 | import com.yanzhenjie.andserver.framework.view.View; 27 | import com.yanzhenjie.andserver.http.HttpRequest; 28 | import com.yanzhenjie.andserver.http.HttpResponse; 29 | import com.yanzhenjie.andserver.http.ResponseBody; 30 | 31 | import java.io.IOException; 32 | 33 | /** 34 | * Created by YanZhenjie on 2018/9/4. 35 | */ 36 | public abstract class Website implements HandlerAdapter, ETag, LastModified { 37 | 38 | @Nullable 39 | @Override 40 | public String getETag(@NonNull HttpRequest request) throws IOException { 41 | return null; 42 | } 43 | 44 | @Override 45 | public long getLastModified(@NonNull HttpRequest request) throws IOException { 46 | return 0; 47 | } 48 | 49 | @Nullable 50 | @Override 51 | public RequestHandler getHandler(@NonNull HttpRequest request) { 52 | return new RequestHandler() { 53 | @Nullable 54 | @Override 55 | public String getETag(@NonNull HttpRequest request) throws IOException { 56 | return Website.this.getETag(request); 57 | } 58 | 59 | @Override 60 | public long getLastModified(@NonNull HttpRequest request) throws IOException { 61 | return Website.this.getLastModified(request); 62 | } 63 | 64 | @Override 65 | public View handle(@NonNull HttpRequest request, @NonNull HttpResponse response) throws IOException { 66 | return new BodyView(getBody(request)); 67 | } 68 | }; 69 | } 70 | 71 | @NonNull 72 | public abstract ResponseBody getBody(@NonNull HttpRequest request) throws IOException; 73 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/http/HttpContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 YanZhenjie. 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 | package com.yanzhenjie.andserver.http; 17 | 18 | import android.support.annotation.NonNull; 19 | import android.support.annotation.Nullable; 20 | 21 | /** 22 | * Created by YanZhenjie on 2018/8/31. 23 | */ 24 | public interface HttpContext { 25 | 26 | String RESPONSE_PRODUCE_TYPE = "http.response.Produce"; 27 | 28 | String REQUEST_CREATED_SESSION = "http.request.Session"; 29 | 30 | String HTTP_MESSAGE_CONVERTER = "http.message.converter"; 31 | 32 | /** 33 | * Obtains attribute with the given name. 34 | * 35 | * @param id the attribute name. 36 | * 37 | * @return attribute value, or {@code null} if not set. 38 | */ 39 | @Nullable 40 | Object getAttribute(@NonNull String id); 41 | 42 | /** 43 | * Sets value of the attribute with the given name. 44 | * 45 | * @param id the attribute name. 46 | * @param obj the attribute value. 47 | */ 48 | void setAttribute(@NonNull String id, @Nullable Object obj); 49 | 50 | /** 51 | * Removes attribute with the given name from the context. 52 | * 53 | * @param id the attribute name. 54 | * 55 | * @return attribute value, or {@code null} if not set. 56 | */ 57 | @Nullable 58 | Object removeAttribute(@NonNull String id); 59 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/http/HttpMethod.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 YanZhenjie. 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 | package com.yanzhenjie.andserver.http; 17 | 18 | import java.util.Locale; 19 | 20 | /** 21 | * Created by YanZhenjie on 2018/8/29. 22 | */ 23 | public enum HttpMethod { 24 | 25 | GET("GET"), 26 | HEAD("HEAD"), 27 | POST("POST"), 28 | PUT("PUT"), 29 | PATCH("PATCH"), 30 | DELETE("DELETE"), 31 | OPTIONS("OPTIONS"), 32 | TRACE("TRACE"); 33 | 34 | private String value; 35 | 36 | HttpMethod(String value) { 37 | this.value = value; 38 | } 39 | 40 | public String value() { 41 | return value; 42 | } 43 | 44 | /** 45 | * Whether to allow the body to be transmitted. 46 | * 47 | * @return true, otherwise is false. 48 | */ 49 | public boolean allowBody() { 50 | switch (this) { 51 | case POST: 52 | case PUT: 53 | case PATCH: 54 | case DELETE: 55 | return true; 56 | default: 57 | return false; 58 | } 59 | } 60 | 61 | /** 62 | * Reverse the text for the request value. 63 | * 64 | * @param method value text, such as: GET, POST. 65 | * 66 | * @return {@link HttpMethod}. 67 | */ 68 | public static HttpMethod reverse(String method) { 69 | method = method.toUpperCase(Locale.ENGLISH); 70 | switch (method) { 71 | case "GET": { 72 | return GET; 73 | } 74 | case "HEAD": { 75 | return HEAD; 76 | } 77 | case "POST": { 78 | return POST; 79 | } 80 | case "PUT": { 81 | return PUT; 82 | } 83 | case "PATCH": { 84 | return PATCH; 85 | } 86 | case "DELETE": { 87 | return DELETE; 88 | } 89 | case "OPTIONS": { 90 | return OPTIONS; 91 | } 92 | case "TRACE": { 93 | return TRACE; 94 | } 95 | default: { 96 | String message = String.format("The value %1$s is not supported.", method); 97 | throw new UnsupportedOperationException(message); 98 | } 99 | } 100 | } 101 | 102 | @Override 103 | public String toString() { 104 | return value; 105 | } 106 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/http/RequestBody.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.http; 17 | 18 | import android.support.annotation.NonNull; 19 | import android.support.annotation.Nullable; 20 | 21 | import com.yanzhenjie.andserver.util.MediaType; 22 | 23 | import java.io.IOException; 24 | import java.io.InputStream; 25 | 26 | /** 27 | * Created by YanZhenjie on 2018/8/9. 28 | */ 29 | public interface RequestBody { 30 | 31 | /** 32 | * Retrieve the character encoding for the request. 33 | * 34 | * @return the character encoding for the request. 35 | */ 36 | String contentEncoding(); 37 | 38 | /** 39 | * Get the {@code Content-Length} of the message body, if the length is unknown, return a negative value. 40 | * 41 | * @return message length. 42 | */ 43 | long length(); 44 | 45 | /** 46 | * Get the {@code Content-Type} of the message body, including charset. 47 | * 48 | * @return e.g. {@code application/json; charset=utf-8}, or {@code null} if the content type is unknown. 49 | */ 50 | @Nullable 51 | MediaType contentType(); 52 | 53 | /** 54 | * Returns a content stream of this body. 55 | * 56 | * @return content stream of this body. 57 | * 58 | * @throws IOException if the stream could not be created. 59 | */ 60 | @NonNull 61 | InputStream stream() throws IOException; 62 | 63 | /** 64 | * Convert the request body to a String. 65 | * 66 | * @return string. 67 | * 68 | * @throws IOException if the stream could not be created. 69 | */ 70 | @NonNull 71 | String string() throws IOException; 72 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/http/RequestDispatcher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 YanZhenjie. 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 | package com.yanzhenjie.andserver.http; 17 | 18 | import android.support.annotation.NonNull; 19 | 20 | /** 21 | * Created by YanZhenjie on 2018/8/31. 22 | */ 23 | public interface RequestDispatcher { 24 | 25 | /** 26 | * Forwards a request from a handler to another handler on the server. 27 | * 28 | * @param request the current request. 29 | * @param response the current response. 30 | */ 31 | void forward(@NonNull HttpRequest request, @NonNull HttpResponse response); 32 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/http/ResponseBody.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.http; 17 | 18 | import android.support.annotation.NonNull; 19 | import android.support.annotation.Nullable; 20 | 21 | import com.yanzhenjie.andserver.util.MediaType; 22 | 23 | import java.io.IOException; 24 | import java.io.OutputStream; 25 | 26 | /** 27 | * Created by YanZhenjie on 2018/8/3. 28 | */ 29 | public interface ResponseBody { 30 | 31 | /** 32 | * Get the content-length of the message body, if the length is unknown, return a negative value. 33 | * 34 | * @return message length. 35 | */ 36 | long contentLength(); 37 | 38 | /** 39 | * Get the content-type of the message body, including charset. 40 | * 41 | * @return e.g. {@code application/json; charset=utf-8}. 42 | */ 43 | @Nullable 44 | MediaType contentType(); 45 | 46 | /** 47 | * Write the body to the output stream. 48 | * 49 | * @param output the output stream to write the body. 50 | */ 51 | void writeTo(@NonNull OutputStream output) throws IOException; 52 | 53 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/http/ResponseWrapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 YanZhenjie. 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 | package com.yanzhenjie.andserver.http; 17 | 18 | import android.support.annotation.NonNull; 19 | import android.support.annotation.Nullable; 20 | 21 | import com.yanzhenjie.andserver.http.cookie.Cookie; 22 | 23 | import java.util.List; 24 | 25 | /** 26 | * Created by YanZhenjie on 2018/9/6. 27 | */ 28 | public class ResponseWrapper implements HttpResponse { 29 | 30 | private HttpResponse mResponse; 31 | 32 | public ResponseWrapper(HttpResponse response) { 33 | this.mResponse = response; 34 | } 35 | 36 | /** 37 | * Get the original response object. 38 | * 39 | * @return {@link HttpResponse}. 40 | */ 41 | public HttpResponse getResponse() { 42 | return mResponse; 43 | } 44 | 45 | @Override 46 | public void setStatus(int sc) { 47 | mResponse.setStatus(sc); 48 | } 49 | 50 | @Override 51 | public int getStatus() { 52 | return mResponse.getStatus(); 53 | } 54 | 55 | @Override 56 | public void setHeader(@NonNull String name, @NonNull String value) { 57 | mResponse.setHeader(name, value); 58 | } 59 | 60 | @Override 61 | public void addHeader(@NonNull String name, @NonNull String value) { 62 | mResponse.addHeader(name, value); 63 | } 64 | 65 | @Nullable 66 | @Override 67 | public String getHeader(@NonNull String name) { 68 | return mResponse.getHeader(name); 69 | } 70 | 71 | @Override 72 | public void setDateHeader(@NonNull String name, long date) { 73 | mResponse.setDateHeader(name, date); 74 | } 75 | 76 | @Override 77 | public void addDateHeader(@NonNull String name, long date) { 78 | mResponse.addDateHeader(name, date); 79 | } 80 | 81 | @Override 82 | public void setIntHeader(@NonNull String name, int value) { 83 | mResponse.setIntHeader(name, value); 84 | } 85 | 86 | @Override 87 | public void addIntHeader(@NonNull String name, int value) { 88 | mResponse.addIntHeader(name, value); 89 | } 90 | 91 | @Override 92 | public boolean containsHeader(@NonNull String name) { 93 | return mResponse.containsHeader(name); 94 | } 95 | 96 | @NonNull 97 | @Override 98 | public List getHeaders(@NonNull String name) { 99 | return mResponse.getHeaders(name); 100 | } 101 | 102 | @NonNull 103 | @Override 104 | public List getHeaderNames() { 105 | return mResponse.getHeaderNames(); 106 | } 107 | 108 | @Override 109 | public void addCookie(@NonNull Cookie cookie) { 110 | mResponse.addCookie(cookie); 111 | } 112 | 113 | @Override 114 | public void sendRedirect(@NonNull String location) { 115 | mResponse.sendRedirect(location); 116 | } 117 | 118 | @Override 119 | public void setBody(ResponseBody body) { 120 | mResponse.setBody(body); 121 | } 122 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/http/StandardContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 YanZhenjie. 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 | package com.yanzhenjie.andserver.http; 17 | 18 | import android.support.annotation.NonNull; 19 | import android.support.annotation.Nullable; 20 | 21 | /** 22 | * Created by YanZhenjie on 2018/8/31. 23 | */ 24 | public class StandardContext implements HttpContext { 25 | 26 | private org.apache.httpcore.protocol.HttpContext mContext; 27 | 28 | public StandardContext(org.apache.httpcore.protocol.HttpContext context) { 29 | this.mContext = context; 30 | } 31 | 32 | @Nullable 33 | @Override 34 | public Object getAttribute(@NonNull String id) { 35 | return mContext.getAttribute(id); 36 | } 37 | 38 | @Override 39 | public void setAttribute(@NonNull String id, @NonNull Object obj) { 40 | mContext.setAttribute(id, obj); 41 | } 42 | 43 | @Nullable 44 | @Override 45 | public Object removeAttribute(@NonNull String id) { 46 | return mContext.removeAttribute(id); 47 | } 48 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/http/cookie/CookieProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.http.cookie; 17 | 18 | import android.support.annotation.NonNull; 19 | import android.support.annotation.Nullable; 20 | 21 | import org.apache.httpcore.Header; 22 | 23 | import java.util.List; 24 | 25 | /** 26 | * Created by YanZhenjie on 2018/7/27. 27 | */ 28 | public interface CookieProcessor { 29 | 30 | /** 31 | * Parse the provided headers into server cookie objects. 32 | * 33 | * @param headers the HTTP headers to parse. 34 | */ 35 | @NonNull 36 | List parseCookieHeader(@Nullable Header[] headers); 37 | 38 | /** 39 | * Generate the {@code Set-Cookie} HTTP header value for the given {@code Cookie}. 40 | * 41 | * @param cookie the cookie for which the header will be generated. 42 | * 43 | * @return the header value in a form that can be added directly to the response. 44 | */ 45 | @NonNull 46 | String generateHeader(@NonNull Cookie cookie); 47 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/http/multipart/BodyContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.http.multipart; 17 | 18 | import android.support.annotation.NonNull; 19 | 20 | import com.yanzhenjie.andserver.http.RequestBody; 21 | import com.yanzhenjie.andserver.util.MediaType; 22 | 23 | import org.apache.commons.fileupload.UploadContext; 24 | 25 | import java.io.IOException; 26 | import java.io.InputStream; 27 | 28 | /** 29 | * Created by YanZhenjie on 2018/8/9. 30 | */ 31 | public class BodyContext implements UploadContext { 32 | 33 | private final RequestBody mBody; 34 | 35 | public BodyContext(@NonNull RequestBody body) { 36 | this.mBody = body; 37 | } 38 | 39 | @Override 40 | public String getCharacterEncoding() { 41 | return mBody.contentEncoding(); 42 | } 43 | 44 | @Override 45 | public String getContentType() { 46 | MediaType contentType = mBody.contentType(); 47 | return contentType == null ? null : contentType.toString(); 48 | } 49 | 50 | @Override 51 | public int getContentLength() { 52 | long contentLength = contentLength(); 53 | return contentLength > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)contentLength; 54 | } 55 | 56 | @Override 57 | public long contentLength() { 58 | return mBody.length(); 59 | } 60 | 61 | @Override 62 | public InputStream getInputStream() throws IOException { 63 | return mBody.stream(); 64 | } 65 | 66 | @Override 67 | public String toString() { 68 | return String.format("ContentLength=%s, Mime=%s", contentLength(), getContentType()); 69 | } 70 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/http/multipart/MultipartFile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.http.multipart; 17 | 18 | import android.support.annotation.NonNull; 19 | import android.support.annotation.Nullable; 20 | 21 | import com.yanzhenjie.andserver.util.MediaType; 22 | 23 | import org.apache.commons.fileupload.FileItem; 24 | 25 | import java.io.File; 26 | import java.io.IOException; 27 | import java.io.InputStream; 28 | 29 | /** 30 | * Created by YanZhenjie on 2018/6/18. 31 | */ 32 | public interface MultipartFile { 33 | 34 | /** 35 | * Return the name of the parameter in the multipart form. 36 | * 37 | * @return the name of the parameter. 38 | */ 39 | @NonNull 40 | String getName(); 41 | 42 | /** 43 | * Return the original filename in the client's filesystem. 44 | * 45 | * @return the original filename, or the empty String if no file, or null if not defined. 46 | * 47 | * @see FileItem#getName() 48 | */ 49 | @Nullable 50 | String getFilename(); 51 | 52 | /** 53 | * Return the content type of the file. 54 | * 55 | * @return the content type, or the empty String if no file, or null if not defined. 56 | */ 57 | @NonNull 58 | MediaType getContentType(); 59 | 60 | /** 61 | * Return whether the uploaded file is empty. 62 | * 63 | * @return true, otherwise is false. 64 | */ 65 | boolean isEmpty(); 66 | 67 | /** 68 | * Return the size of the file in bytes. 69 | * 70 | * @return the size of the file, or 0 if empty. 71 | */ 72 | long getSize(); 73 | 74 | /** 75 | * Return the contents of the file as an array of bytes. 76 | * 77 | * @return the contents of the file as bytes, or an empty byte array if empty. 78 | * 79 | * @throws IOException in case of access errors (if the temporary store fails). 80 | */ 81 | byte[] getBytes() throws IOException; 82 | 83 | /** 84 | * Return an {@code InputStream} to read the contents of the file from. 85 | * 86 | * @return the contents of the file as stream, or an empty stream if empty. 87 | * 88 | * @throws IOException in case of access errors. 89 | */ 90 | @NonNull 91 | InputStream getStream() throws IOException; 92 | 93 | /** 94 | * Writing the received file to the given destination file. If the destination file already exists, it will be 95 | * deleted first. 96 | * 97 | *

If the target file has been written to disk, this operation cannot be invoked again afterwards. 98 | * 99 | * @param dest the destination file. 100 | */ 101 | void transferTo(@NonNull File dest) throws IOException, IllegalStateException; 102 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/http/multipart/MultipartRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.http.multipart; 17 | 18 | import android.support.annotation.NonNull; 19 | import android.support.annotation.Nullable; 20 | 21 | import com.yanzhenjie.andserver.http.HttpRequest; 22 | import com.yanzhenjie.andserver.util.MultiValueMap; 23 | 24 | import java.util.Iterator; 25 | import java.util.List; 26 | import java.util.Map; 27 | 28 | /** 29 | *

This interface defines the multipart request access operations that are exposed for actual multipart requests. 30 | *

31 | * 32 | * Created by YanZhenjie on 2018/6/21. 33 | */ 34 | public interface MultipartRequest extends HttpRequest { 35 | 36 | /** 37 | *

Return an {@link java.util.Iterator} of String objects containing the parameter names of the multipart files 38 | * contained in this request. These are the field names of the form (like with normal parameters), not the original 39 | * file names.

40 | * 41 | * @return the names of the files. 42 | */ 43 | @NonNull 44 | Iterator getFileNames(); 45 | 46 | /** 47 | * Return the contents plus description of an uploaded file in this request, or null if it does not exist. 48 | * 49 | * @param name parameter name. 50 | * 51 | * @return a {@link MultipartFile} object. 52 | */ 53 | @Nullable 54 | MultipartFile getFile(String name); 55 | 56 | /** 57 | * Return the contents plus description of uploaded files in this request, or an empty list if it does not exist. 58 | * 59 | * @param name parameter name. 60 | * 61 | * @return a {@link MultipartFile} list. 62 | */ 63 | @Nullable 64 | List getFiles(String name); 65 | 66 | /** 67 | * Return a {@link java.util.Map} of the multipart files contained in this request. 68 | * 69 | * @return a map containing the parameter names as keys, and the {@link MultipartFile} objects as values. 70 | */ 71 | @NonNull 72 | Map getFileMap(); 73 | 74 | /** 75 | * Return a {@link MultiValueMap} of the multipart files contained in this request. 76 | * 77 | * @return a map containing the parameter names as keys, and a list of {@link MultipartFile} objects as values. 78 | */ 79 | @NonNull 80 | MultiValueMap getMultiFileMap(); 81 | 82 | /** 83 | * Determine the content type of the specified request part. 84 | * 85 | * @param paramOrFileName the name of the part. 86 | * 87 | * @return the associated content type, or null if not defined. 88 | */ 89 | @Nullable 90 | String getMultipartContentType(String paramOrFileName); 91 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/http/multipart/MultipartResolver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.http.multipart; 17 | 18 | import com.yanzhenjie.andserver.http.HttpRequest; 19 | import com.yanzhenjie.andserver.error.MultipartException; 20 | 21 | /** 22 | * Created by YanZhenjie on 2018/8/8. 23 | */ 24 | public interface MultipartResolver { 25 | 26 | /** 27 | * Determine if the given request contains multipart content, will typically check for content type 28 | * "multipart/form-data". 29 | * 30 | * @param request the request to be evaluated. 31 | * 32 | * @return whether the request contains multipart content. 33 | */ 34 | boolean isMultipart(HttpRequest request); 35 | 36 | /** 37 | * Parse the given request into multipart files and parameters, and wrap the request inside a {@link 38 | * MultipartRequest} object that provides access to file descriptors and makes contained parameters accessible via 39 | * the standard HttpRequest methods. 40 | * 41 | * @param request the request to wrap (must be of a multipart content type). 42 | * 43 | * @return the wrapped request. 44 | * 45 | * @throws MultipartException if the request is not multipart, or encounter other problems. 46 | */ 47 | MultipartRequest resolveMultipart(HttpRequest request) throws MultipartException; 48 | 49 | /** 50 | * Cleanup any resources used for the multipart handling, like a storage for the uploaded files. 51 | * 52 | * @param request the request to cleanup resources for. 53 | */ 54 | void cleanupMultipart(MultipartRequest request); 55 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/http/session/IdGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.http.session; 17 | 18 | import android.support.annotation.NonNull; 19 | 20 | /** 21 | * Created by YanZhenjie on 2018/7/26. 22 | */ 23 | public interface IdGenerator { 24 | 25 | /** 26 | * Generate and return a new identifier. 27 | * 28 | * @return the newly generated id. 29 | */ 30 | @NonNull 31 | String generateId(); 32 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/http/session/SessionManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.http.session; 17 | 18 | import android.support.annotation.NonNull; 19 | import android.support.annotation.Nullable; 20 | 21 | import java.io.IOException; 22 | 23 | /** 24 | * Created by YanZhenjie on 2018/7/26. 25 | */ 26 | public interface SessionManager { 27 | 28 | /** 29 | * Add this session to the set of active sessions for this {@code SessionManager}. 30 | * 31 | * @param session session to be added. 32 | * 33 | * @throws IOException if an output error occurs while processing this request. 34 | */ 35 | void add(@NonNull Session session) throws IOException; 36 | 37 | /** 38 | * Change the session ID of the current session to a new randomly generated session ID. 39 | * 40 | * @param session the session to change the session ID for. 41 | */ 42 | void changeSessionId(@NonNull Session session); 43 | 44 | /** 45 | * Create a new session object. 46 | * 47 | * @return an empty session object. 48 | */ 49 | @NonNull 50 | Session createSession(); 51 | 52 | /** 53 | * Return the active session, with the specified session id (if any); otherwise return {@code null}. 54 | * 55 | * @param id the session id for the session to be returned. 56 | * 57 | * @return the request session or {@code null}. 58 | * 59 | * @throws IllegalStateException if a new session cannot be instantiated for any reason. 60 | * @throws IOException if an output error occurs while processing this request. 61 | */ 62 | @Nullable 63 | Session findSession(@NonNull String id) throws IOException, ClassNotFoundException; 64 | 65 | /** 66 | * Remove this session from the active sessions for this {@code SessionManager}. 67 | * 68 | * @param session session to be removed. 69 | */ 70 | void remove(@NonNull Session session); 71 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/http/session/StandardIdGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package com.yanzhenjie.andserver.http.session; 18 | 19 | import android.support.annotation.NonNull; 20 | 21 | import java.security.NoSuchAlgorithmException; 22 | import java.security.SecureRandom; 23 | 24 | public class StandardIdGenerator implements IdGenerator { 25 | 26 | private static final int ID_LENGTH = 30; 27 | 28 | private SecureRandom mRandom; 29 | 30 | public StandardIdGenerator() { 31 | this.mRandom = createSecureRandom(); 32 | } 33 | 34 | @NonNull 35 | @Override 36 | public String generateId() { 37 | byte random[] = new byte[16]; 38 | 39 | // Render the result as a String of hexadecimal digits. 40 | // Start with enough space for sessionIdLength and medium route size. 41 | StringBuilder buffer = new StringBuilder(2 * ID_LENGTH + 20); 42 | 43 | int resultLenBytes = 0; 44 | 45 | while (resultLenBytes < ID_LENGTH) { 46 | mRandom.nextBytes(random); 47 | for (int j = 0; j < random.length && resultLenBytes < ID_LENGTH; j++) { 48 | byte b1 = (byte)((random[j] & 0xf0) >> 4); 49 | byte b2 = (byte)(random[j] & 0x0f); 50 | if (b1 < 10) { 51 | buffer.append((char)('0' + b1)); 52 | } else { 53 | buffer.append((char)('A' + (b1 - 10))); 54 | } 55 | if (b2 < 10) { 56 | buffer.append((char)('0' + b2)); 57 | } else { 58 | buffer.append((char)('A' + (b2 - 10))); 59 | } 60 | resultLenBytes++; 61 | } 62 | } 63 | return buffer.toString(); 64 | } 65 | 66 | /** 67 | * Create a new random number generator instance we should use for generating session identifiers. 68 | */ 69 | private SecureRandom createSecureRandom() { 70 | SecureRandom result; 71 | try { 72 | result = SecureRandom.getInstance("SHA1PRNG"); 73 | } catch (NoSuchAlgorithmException e) { 74 | result = new SecureRandom(); 75 | } 76 | 77 | // Force seeding to take place. 78 | result.nextInt(); 79 | return result; 80 | } 81 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/http/session/StandardSessionManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.http.session; 17 | 18 | import android.content.Context; 19 | import android.support.annotation.NonNull; 20 | import android.support.annotation.Nullable; 21 | 22 | import java.io.File; 23 | import java.io.IOException; 24 | 25 | /** 26 | * Created by YanZhenjie on 2018/7/26. 27 | */ 28 | public class StandardSessionManager implements SessionManager { 29 | 30 | private IdGenerator mIdGenerator; 31 | private Store mStore; 32 | 33 | public StandardSessionManager(Context context) { 34 | this.mIdGenerator = new StandardIdGenerator(); 35 | 36 | File sessionDir = new File(context.getCacheDir(), "andserver_session"); 37 | this.mStore = new StandardStore(sessionDir); 38 | } 39 | 40 | @Override 41 | public void add(@NonNull Session session) throws IOException { 42 | if (session instanceof StandardSession && session.isNew()) { 43 | StandardSession standardSession = (StandardSession)session; 44 | standardSession.setNew(false); 45 | mStore.replace(standardSession); 46 | } 47 | } 48 | 49 | @Override 50 | public void changeSessionId(@NonNull Session session) { 51 | if (session instanceof StandardSession) { 52 | StandardSession standardSession = (StandardSession)session; 53 | standardSession.setId(mIdGenerator.generateId()); 54 | } 55 | } 56 | 57 | @NonNull 58 | @Override 59 | public Session createSession() { 60 | StandardSession session = newSession(); 61 | session.setId(mIdGenerator.generateId()); 62 | return session; 63 | } 64 | 65 | @Nullable 66 | @Override 67 | public Session findSession(@NonNull String id) throws IOException, ClassNotFoundException { 68 | StandardSession session = mStore.getSession(id); 69 | if (session != null) session.setLastAccessedTime(System.currentTimeMillis()); 70 | return session; 71 | } 72 | 73 | @Override 74 | public void remove(@NonNull Session session) { 75 | if (session instanceof StandardSession) { 76 | mStore.remove((StandardSession)session); 77 | } 78 | } 79 | 80 | private StandardSession newSession() { 81 | StandardSession session = new StandardSession(); 82 | long currentTime = System.currentTimeMillis(); 83 | session.setCreatedTime(currentTime); 84 | session.setLastAccessedTime(currentTime); 85 | session.setNew(true); 86 | session.setValid(true); 87 | return session; 88 | } 89 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/http/session/StandardStore.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.http.session; 17 | 18 | import android.support.annotation.NonNull; 19 | import android.support.annotation.Nullable; 20 | 21 | import com.yanzhenjie.andserver.util.Assert; 22 | import com.yanzhenjie.andserver.util.IOUtils; 23 | import com.yanzhenjie.andserver.util.StringUtils; 24 | 25 | import java.io.File; 26 | import java.io.FileInputStream; 27 | import java.io.FileOutputStream; 28 | import java.io.IOException; 29 | import java.io.ObjectInputStream; 30 | import java.io.ObjectOutputStream; 31 | 32 | /** 33 | * Created by YanZhenjie on 2018/7/26. 34 | */ 35 | public class StandardStore implements Store { 36 | 37 | private File mDirectory; 38 | 39 | public StandardStore(File directory) { 40 | this.mDirectory = directory; 41 | } 42 | 43 | @Override 44 | public boolean replace(@NonNull StandardSession session) throws IOException { 45 | Assert.notNull(session, "The session can not be null."); 46 | 47 | String id = session.getId(); 48 | if (StringUtils.isEmpty(id)) throw new IllegalStateException("The session id can not be empty or null."); 49 | 50 | ObjectOutputStream writer = null; 51 | try { 52 | if (!IOUtils.createFolder(mDirectory)) return false; 53 | 54 | File file = new File(mDirectory, id); 55 | if (!IOUtils.createNewFile(file)) return false; 56 | 57 | writer = new ObjectOutputStream(new FileOutputStream(file)); 58 | session.writeObject(writer); 59 | return true; 60 | } catch (IOException e) { 61 | IOUtils.delFileOrFolder(new File(mDirectory, id)); 62 | throw e; 63 | } finally { 64 | IOUtils.closeQuietly(writer); 65 | } 66 | } 67 | 68 | @Nullable 69 | @Override 70 | public StandardSession getSession(@NonNull String id) throws IOException, ClassNotFoundException { 71 | if (StringUtils.isEmpty(id)) throw new IllegalArgumentException("The id can not be empty or null."); 72 | 73 | ObjectInputStream reader = null; 74 | try { 75 | File file = new File(mDirectory, id); 76 | if (!file.exists() || file.isDirectory()) return null; 77 | 78 | reader = new ObjectInputStream(new FileInputStream(file)); 79 | StandardSession session = new StandardSession(); 80 | session.readObject(reader); 81 | return session; 82 | } catch (IOException e) { 83 | IOUtils.delFileOrFolder(new File(mDirectory, id)); 84 | throw e; 85 | } finally { 86 | IOUtils.closeQuietly(reader); 87 | } 88 | } 89 | 90 | @Override 91 | public boolean remove(@NonNull StandardSession session) { 92 | String id = session.getId(); 93 | if (StringUtils.isEmpty(id)) throw new IllegalStateException("The session id can not be empty or null."); 94 | return IOUtils.delFileOrFolder(new File(mDirectory, session.getId())); 95 | } 96 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/http/session/Store.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.http.session; 17 | 18 | import android.support.annotation.NonNull; 19 | import android.support.annotation.Nullable; 20 | 21 | import java.io.IOException; 22 | 23 | /** 24 | * Created by YanZhenjie on 2018/7/26. 25 | */ 26 | interface Store { 27 | 28 | /** 29 | * Increase the session to the persistent store. 30 | * 31 | * @param session the session. 32 | * 33 | * @return true if it is successfully added or replaced, otherwise is false. 34 | * 35 | * @throws IOException if an output error occurs while processing this request. 36 | */ 37 | boolean replace(@NonNull StandardSession session) throws IOException; 38 | 39 | /** 40 | * Get the session from the persistent store. 41 | * 42 | * @param id the session ID. 43 | * 44 | * @return a session object. 45 | * 46 | * @throws IOException if the input error occurs while processing this request. 47 | */ 48 | @Nullable 49 | StandardSession getSession(@NonNull String id) throws IOException, ClassNotFoundException; 50 | 51 | /** 52 | * Remove the session from the persistent store. 53 | * 54 | * @param session the session. 55 | * 56 | * @return true if successful removal, otherwise is false. 57 | */ 58 | boolean remove(@NonNull StandardSession session); 59 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/mapping/Addition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.mapping; 17 | 18 | import android.support.annotation.NonNull; 19 | 20 | /** 21 | * Created by YanZhenjie on 2018/9/9. 22 | */ 23 | public class Addition { 24 | 25 | private String[] stringType; 26 | private boolean[] booleanType; 27 | private int[] intType; 28 | private long[] longType; 29 | private short[] shortType; 30 | private float[] floatType; 31 | private double[] doubleType; 32 | private byte[] byteType; 33 | private char[] charType; 34 | 35 | public Addition() { 36 | } 37 | 38 | @NonNull 39 | public String[] getStringType() { 40 | return stringType; 41 | } 42 | 43 | public void setStringType(String[] stringType) { 44 | this.stringType = stringType; 45 | } 46 | 47 | @NonNull 48 | public boolean[] getBooleanType() { 49 | return booleanType; 50 | } 51 | 52 | public void setBooleanType(boolean[] booleanType) { 53 | this.booleanType = booleanType; 54 | } 55 | 56 | @NonNull 57 | public int[] getIntType() { 58 | return intType; 59 | } 60 | 61 | public void setIntType(int[] intType) { 62 | this.intType = intType; 63 | } 64 | 65 | @NonNull 66 | public long[] getLongType() { 67 | return longType; 68 | } 69 | 70 | public void setLongType(long[] longType) { 71 | this.longType = longType; 72 | } 73 | 74 | @NonNull 75 | public short[] getShortType() { 76 | return shortType; 77 | } 78 | 79 | public void setShortType(short[] shortType) { 80 | this.shortType = shortType; 81 | } 82 | 83 | @NonNull 84 | public float[] getFloatType() { 85 | return floatType; 86 | } 87 | 88 | public void setFloatType(float[] floatType) { 89 | this.floatType = floatType; 90 | } 91 | 92 | @NonNull 93 | public double[] getDoubleType() { 94 | return doubleType; 95 | } 96 | 97 | public void setDoubleType(double[] doubleType) { 98 | this.doubleType = doubleType; 99 | } 100 | 101 | @NonNull 102 | public byte[] getByteType() { 103 | return byteType; 104 | } 105 | 106 | public void setByteType(byte[] byteType) { 107 | this.byteType = byteType; 108 | } 109 | 110 | @NonNull 111 | public char[] getCharType() { 112 | return charType; 113 | } 114 | 115 | public void setCharType(char[] charType) { 116 | this.charType = charType; 117 | } 118 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/mapping/Mapping.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.mapping; 17 | 18 | /** 19 | *

Save the request mapping configuration.

20 | * 21 | * Created by YanZhenjie on 2018/6/13. 22 | */ 23 | public class Mapping { 24 | 25 | private Path mPath; 26 | private Method mMethod; 27 | private Pair mParam; 28 | private Pair mHeader; 29 | private Mime mConsume; 30 | private Mime mProduce; 31 | 32 | public Mapping() { 33 | } 34 | 35 | public Path getPath() { 36 | return mPath; 37 | } 38 | 39 | public void setPath(Path path) { 40 | mPath = path; 41 | } 42 | 43 | public Method getMethod() { 44 | return mMethod; 45 | } 46 | 47 | public void setMethod(Method method) { 48 | mMethod = method; 49 | } 50 | 51 | public Pair getParam() { 52 | return mParam; 53 | } 54 | 55 | public void setParam(Pair param) { 56 | mParam = param; 57 | } 58 | 59 | public Pair getHeader() { 60 | return mHeader; 61 | } 62 | 63 | public void setHeader(Pair header) { 64 | mHeader = header; 65 | } 66 | 67 | public Mime getConsume() { 68 | return mConsume; 69 | } 70 | 71 | public void setConsume(Mime consume) { 72 | mConsume = consume; 73 | } 74 | 75 | public Mime getProduce() { 76 | return mProduce; 77 | } 78 | 79 | public void setProduce(Mime produce) { 80 | mProduce = produce; 81 | } 82 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/mapping/Method.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.mapping; 17 | 18 | import android.support.annotation.NonNull; 19 | 20 | import com.yanzhenjie.andserver.http.HttpMethod; 21 | 22 | import java.util.LinkedList; 23 | import java.util.List; 24 | 25 | /** 26 | * Created by YanZhenjie on 2018/6/14. 27 | */ 28 | public class Method { 29 | 30 | private List mRuleList = new LinkedList<>(); 31 | 32 | public Method() { 33 | } 34 | 35 | @NonNull 36 | public List getRuleList() { 37 | return mRuleList; 38 | } 39 | 40 | public void addRule(@NonNull String ruleText) { 41 | mRuleList.add(HttpMethod.reverse(ruleText)); 42 | } 43 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/mapping/Mime.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.mapping; 17 | 18 | import android.support.annotation.NonNull; 19 | 20 | import com.yanzhenjie.andserver.util.MediaType; 21 | 22 | import java.util.LinkedList; 23 | import java.util.List; 24 | import java.util.Map; 25 | 26 | /** 27 | * Created by YanZhenjie on 2018/6/14. 28 | */ 29 | public class Mime { 30 | 31 | private List mRuleList = new LinkedList<>(); 32 | 33 | public Mime() { 34 | } 35 | 36 | @NonNull 37 | public List getRuleList() { 38 | return mRuleList; 39 | } 40 | 41 | public void addRule(@NonNull String ruleText) { 42 | MediaType mimeType = MediaType.valueOf(ruleText); 43 | Rule rule = new Rule(mimeType.getType(), mimeType.getSubtype(), mimeType.getParameters()); 44 | mRuleList.add(rule); 45 | } 46 | 47 | public static class Rule extends MediaType { 48 | 49 | public Rule(String type, String subtype, Map parameters) { 50 | super(type, subtype, parameters); 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/mapping/Pair.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.mapping; 17 | 18 | import android.support.annotation.NonNull; 19 | 20 | import com.yanzhenjie.andserver.util.Patterns; 21 | 22 | import java.util.LinkedList; 23 | import java.util.List; 24 | 25 | /** 26 | * Created by YanZhenjie on 2018/6/14. 27 | */ 28 | public class Pair implements Patterns { 29 | 30 | private List mRuleList = new LinkedList<>(); 31 | 32 | public Pair() { 33 | } 34 | 35 | @NonNull 36 | public List getRuleList() { 37 | return mRuleList; 38 | } 39 | 40 | public void addRule(@NonNull String ruleText) { 41 | if (ruleText.matches(PAIR_NO_VALUE)) { 42 | String[] keyValue = ruleText.split("="); 43 | Rule rule = new Rule(); 44 | String key = keyValue[0]; 45 | rule.setKey(key.substring(0, key.length() - 1)); 46 | rule.setValue(keyValue[1]); 47 | rule.setNoValue(true); 48 | mRuleList.add(rule); 49 | } else if (ruleText.matches(PAIR_KEY_VALUE)) { 50 | String[] keyValue = ruleText.split("="); 51 | 52 | Rule rule = new Rule(); 53 | rule.setKey(keyValue[0]); 54 | rule.setValue(keyValue[1]); 55 | mRuleList.add(rule); 56 | } else if (ruleText.matches(PAIR_NO_KEY)) { 57 | Rule rule = new Rule(); 58 | rule.setKey(ruleText.substring(1)); 59 | rule.setNoKey(true); 60 | mRuleList.add(rule); 61 | } else if (ruleText.matches(PAIR_KEY)) { 62 | Rule rule = new Rule(); 63 | rule.setKey(ruleText); 64 | mRuleList.add(rule); 65 | } 66 | } 67 | 68 | public static class Rule { 69 | 70 | private String key; 71 | private String value; 72 | private boolean noKey; 73 | private boolean noValue; 74 | 75 | public Rule() { 76 | } 77 | 78 | public String getKey() { 79 | return key; 80 | } 81 | 82 | public void setKey(String key) { 83 | this.key = key; 84 | } 85 | 86 | public String getValue() { 87 | return value; 88 | } 89 | 90 | public void setValue(String value) { 91 | this.value = value; 92 | } 93 | 94 | public boolean isNoKey() { 95 | return noKey; 96 | } 97 | 98 | public void setNoKey(boolean noKey) { 99 | this.noKey = noKey; 100 | } 101 | 102 | public boolean isNoValue() { 103 | return noValue; 104 | } 105 | 106 | public void setNoValue(boolean noValue) { 107 | this.noValue = noValue; 108 | } 109 | } 110 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/mapping/UnmodifiableMapping.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.mapping; 17 | 18 | /** 19 | * Created by YanZhenjie on 2018/9/9. 20 | */ 21 | public class UnmodifiableMapping extends Mapping { 22 | 23 | private Mapping mMapping; 24 | 25 | public UnmodifiableMapping(Mapping mapping) { 26 | this.mMapping = mapping; 27 | } 28 | 29 | @Override 30 | public Path getPath() { 31 | Path path = mMapping.getPath(); 32 | if (path != null) return new UnmodifiablePath(path); 33 | return null; 34 | } 35 | 36 | @Override 37 | public void setPath(Path path) { 38 | throw new UnsupportedOperationException(); 39 | } 40 | 41 | @Override 42 | public Method getMethod() { 43 | Method method = mMapping.getMethod(); 44 | if (method != null) return new UnmodifiableMethod(method); 45 | return null; 46 | } 47 | 48 | @Override 49 | public void setMethod(Method method) { 50 | throw new UnsupportedOperationException(); 51 | } 52 | 53 | @Override 54 | public Pair getParam() { 55 | Pair param = mMapping.getParam(); 56 | if (param != null) return new UnmodifiablePair(param); 57 | return null; 58 | } 59 | 60 | @Override 61 | public void setParam(Pair param) { 62 | throw new UnsupportedOperationException(); 63 | } 64 | 65 | @Override 66 | public Pair getHeader() { 67 | Pair header = mMapping.getHeader(); 68 | if (header != null) return new UnmodifiablePair(header); 69 | return null; 70 | } 71 | 72 | @Override 73 | public void setHeader(Pair header) { 74 | throw new UnsupportedOperationException(); 75 | } 76 | 77 | @Override 78 | public Mime getConsume() { 79 | Mime consume = mMapping.getConsume(); 80 | if (consume != null) return new UnmodifiableMime(consume); 81 | return null; 82 | } 83 | 84 | @Override 85 | public void setConsume(Mime consume) { 86 | throw new UnsupportedOperationException(); 87 | } 88 | 89 | @Override 90 | public Mime getProduce() { 91 | Mime produce = mMapping.getProduce(); 92 | if (produce != null) return new UnmodifiableMime(produce); 93 | return null; 94 | } 95 | 96 | @Override 97 | public void setProduce(Mime produce) { 98 | throw new UnsupportedOperationException(); 99 | } 100 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/mapping/UnmodifiableMethod.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.mapping; 17 | 18 | import android.support.annotation.NonNull; 19 | 20 | import com.yanzhenjie.andserver.http.HttpMethod; 21 | 22 | import java.util.Collections; 23 | import java.util.List; 24 | 25 | /** 26 | * Created by YanZhenjie on 2018/9/9. 27 | */ 28 | public class UnmodifiableMethod extends Method { 29 | 30 | private Method mMethod; 31 | 32 | public UnmodifiableMethod(Method method) { 33 | this.mMethod = method; 34 | } 35 | 36 | @NonNull 37 | @Override 38 | public List getRuleList() { 39 | return Collections.unmodifiableList(mMethod.getRuleList()); 40 | } 41 | 42 | @Override 43 | public void addRule(@NonNull String ruleText) { 44 | throw new UnsupportedOperationException(); 45 | } 46 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/mapping/UnmodifiableMime.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.mapping; 17 | 18 | import android.support.annotation.NonNull; 19 | 20 | import java.util.Collections; 21 | import java.util.List; 22 | 23 | /** 24 | * Created by YanZhenjie on 2018/9/9. 25 | */ 26 | public class UnmodifiableMime extends Mime { 27 | 28 | private Mime mMime; 29 | 30 | public UnmodifiableMime(Mime mime) { 31 | this.mMime = mime; 32 | } 33 | 34 | @NonNull 35 | @Override 36 | public List getRuleList() { 37 | return Collections.unmodifiableList(mMime.getRuleList()); 38 | } 39 | 40 | @Override 41 | public void addRule(@NonNull String ruleText) { 42 | throw new UnsupportedOperationException(); 43 | } 44 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/mapping/UnmodifiablePair.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.mapping; 17 | 18 | import android.support.annotation.NonNull; 19 | 20 | import java.util.Collections; 21 | import java.util.List; 22 | 23 | /** 24 | * Created by YanZhenjie on 2018/9/9. 25 | */ 26 | public class UnmodifiablePair extends Pair { 27 | 28 | private Pair mPair; 29 | 30 | public UnmodifiablePair(Pair pair) { 31 | this.mPair = pair; 32 | } 33 | 34 | @NonNull 35 | @Override 36 | public List getRuleList() { 37 | return Collections.unmodifiableList(mPair.getRuleList()); 38 | } 39 | 40 | @Override 41 | public void addRule(@NonNull String ruleText) { 42 | throw new UnsupportedOperationException(); 43 | } 44 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/mapping/UnmodifiablePath.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.mapping; 17 | 18 | import android.support.annotation.NonNull; 19 | 20 | import java.util.Collections; 21 | import java.util.List; 22 | 23 | /** 24 | * Created by YanZhenjie on 2018/9/9. 25 | */ 26 | public class UnmodifiablePath extends Path { 27 | 28 | private Path mPath; 29 | 30 | public UnmodifiablePath(Path path) { 31 | this.mPath = path; 32 | } 33 | 34 | @NonNull 35 | @Override 36 | public List getRuleList() { 37 | return Collections.unmodifiableList(mPath.getRuleList()); 38 | } 39 | 40 | @Override 41 | public void addRule(@NonNull String ruleText) { 42 | throw new UnsupportedOperationException(); 43 | } 44 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/register/OnRegister.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 YanZhenjie. 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 | package com.yanzhenjie.andserver.register; 17 | 18 | /** 19 | * Created by YanZhenjie on 2018/9/10. 20 | */ 21 | public interface OnRegister { 22 | 23 | /** 24 | * Register the component. 25 | * 26 | * @param group group name. 27 | * @param register onRegister. 28 | */ 29 | void onRegister(String group, Register register); 30 | 31 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/register/Register.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 YanZhenjie. 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 | package com.yanzhenjie.andserver.register; 17 | 18 | import android.support.annotation.NonNull; 19 | 20 | import com.yanzhenjie.andserver.framework.MessageConverter; 21 | import com.yanzhenjie.andserver.framework.HandlerInterceptor; 22 | import com.yanzhenjie.andserver.framework.ExceptionResolver; 23 | import com.yanzhenjie.andserver.framework.handler.HandlerAdapter; 24 | 25 | /** 26 | * Created by YanZhenjie on 2018/9/10. 27 | */ 28 | public interface Register { 29 | 30 | /** 31 | * Increase the handler adapter. 32 | * 33 | * @param adapter {@link HandlerAdapter}. 34 | */ 35 | void addAdapter(@NonNull HandlerAdapter adapter); 36 | 37 | /** 38 | * Increase handler interceptor. 39 | * 40 | * @param interceptor {@link HandlerInterceptor}. 41 | */ 42 | void addInterceptor(@NonNull HandlerInterceptor interceptor); 43 | 44 | /** 45 | * Set up a message converter to convert messages that are not recognized by AndServer. 46 | * 47 | * @param converter {@link MessageConverter}. 48 | */ 49 | void setConverter(MessageConverter converter); 50 | 51 | /** 52 | * Set the exception handler. If you don't want you to let AndServer output the default error message, set it to 53 | * take over the exception. 54 | * 55 | * @param resolver {@link ExceptionResolver}. 56 | */ 57 | void setResolver(@NonNull ExceptionResolver resolver); 58 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/util/AcceptLanguage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.util; 17 | 18 | import java.util.ArrayList; 19 | import java.util.Collections; 20 | import java.util.List; 21 | import java.util.Locale; 22 | 23 | /** 24 | * Created by YanZhenjie on 2018/8/7. 25 | */ 26 | public class AcceptLanguage { 27 | 28 | private final Locale locale; 29 | private final double quality; 30 | 31 | protected AcceptLanguage(Locale locale, double quality) { 32 | this.locale = locale; 33 | this.quality = quality; 34 | } 35 | 36 | public Locale getLocale() { 37 | return locale; 38 | } 39 | 40 | public double getQuality() { 41 | return quality; 42 | } 43 | 44 | public static List parse(String input) { 45 | if (StringUtils.isEmpty(input)) return Collections.emptyList(); 46 | 47 | String[] segments = input.split(","); 48 | if (ObjectUtils.isEmpty(segments)) return Collections.emptyList(); 49 | 50 | List list = new ArrayList<>(); 51 | for (String segment : segments) { 52 | String[] values = segment.split(";"); 53 | if (values.length == 2 && values[1].length() > 2 && values[1].charAt(0) == 'q' && 54 | values[1].charAt(1) == '=') { 55 | String q = values[1].substring(2); 56 | try { 57 | list.add(new AcceptLanguage(new Locale(values[1]), Double.parseDouble(q))); 58 | } catch (NumberFormatException e) { 59 | e.printStackTrace(); 60 | } 61 | } 62 | } 63 | 64 | return list; 65 | } 66 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/util/Executors.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 YanZhenjie. 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 | package com.yanzhenjie.andserver.util; 17 | 18 | import android.os.Handler; 19 | import android.os.Looper; 20 | 21 | import java.util.concurrent.Callable; 22 | import java.util.concurrent.ExecutorService; 23 | import java.util.concurrent.Future; 24 | 25 | /** 26 | * Created by YanZhenjie on 2018/9/10. 27 | */ 28 | public class Executors { 29 | 30 | private static Executors instance; 31 | 32 | /** 33 | * Get instance. 34 | * 35 | * @return {@link Executors}. 36 | */ 37 | public static Executors getInstance() { 38 | if (instance == null) { 39 | synchronized (Executors.class) { 40 | if (instance == null) instance = new Executors(); 41 | } 42 | } 43 | return instance; 44 | } 45 | 46 | /** 47 | * Executor Service. 48 | */ 49 | private final ExecutorService mService; 50 | 51 | /** 52 | * Handler. 53 | */ 54 | private static Handler mHandler; 55 | 56 | private Executors() { 57 | mService = java.util.concurrent.Executors.newCachedThreadPool(); 58 | mHandler = new Handler(Looper.getMainLooper()); 59 | } 60 | 61 | /** 62 | * Execute a runnable. 63 | */ 64 | public void execute(Runnable runnable) { 65 | mService.execute(runnable); 66 | } 67 | 68 | /** 69 | * Submit a runnable. 70 | */ 71 | public Future submit(Runnable runnable) { 72 | return mService.submit(runnable); 73 | } 74 | 75 | /** 76 | * Submit a runnable. 77 | */ 78 | public Future submit(Runnable runnable, T result) { 79 | return mService.submit(runnable, result); 80 | } 81 | 82 | /** 83 | * Submit a callable. 84 | */ 85 | public Future submit(Callable callable) { 86 | return mService.submit(callable); 87 | } 88 | 89 | /** 90 | * Post a runnable. 91 | */ 92 | public void post(Runnable command) { 93 | mHandler.post(command); 94 | } 95 | 96 | /** 97 | * Delay post a runnable. 98 | */ 99 | public void postDelayed(Runnable command, long delayedMillis) { 100 | mHandler.postDelayed(command, delayedMillis); 101 | } 102 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/util/HttpDateFormat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package com.yanzhenjie.andserver.util; 18 | 19 | import java.text.ParseException; 20 | import java.text.SimpleDateFormat; 21 | import java.util.Date; 22 | import java.util.Locale; 23 | import java.util.TimeZone; 24 | 25 | /** 26 | * Utility class to generate HTTP dates. 27 | * 28 | * @author Remy Maucherat 29 | */ 30 | public final class HttpDateFormat { 31 | 32 | /** 33 | * The date format of the Http header. 34 | */ 35 | private static final String RFC1123_DATE = "EEE, dd MMM yyyy HH:mm:ss zzz"; 36 | private static final SimpleDateFormat[] FORMATS_TEMPLATE = {new SimpleDateFormat(RFC1123_DATE, Locale.US), 37 | new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US), 38 | new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US)}; 39 | 40 | private static final TimeZone GMT_ZONE = TimeZone.getTimeZone("GMT"); 41 | private static final SimpleDateFormat FORMAT = new SimpleDateFormat(RFC1123_DATE, Locale.US); 42 | 43 | static { 44 | FORMAT.setTimeZone(GMT_ZONE); 45 | } 46 | 47 | /** 48 | * Get the current date in HTTP format. 49 | * 50 | * @return the HTTP date. 51 | */ 52 | public static String getCurrentDate() { 53 | synchronized (FORMAT) { 54 | long now = System.currentTimeMillis(); 55 | return FORMAT.format(new Date(now)); 56 | } 57 | } 58 | 59 | /** 60 | * Get the HTTP format of the specified date. 61 | * 62 | * @param value the date. 63 | * 64 | * @return the HTTP date. 65 | */ 66 | public static String formatDate(long value) { 67 | synchronized (HttpDateFormat.class) { 68 | Date dateValue = new Date(value); 69 | return FORMAT.format(dateValue); 70 | } 71 | } 72 | 73 | /** 74 | * Try to parse the given date as a HTTP date. 75 | * 76 | * @param value the HTTP date. 77 | * 78 | * @return the date as a long. 79 | */ 80 | public static long parseDate(String value) { 81 | Date date = null; 82 | for (SimpleDateFormat format : FORMATS_TEMPLATE) { 83 | try { 84 | date = format.parse(value); 85 | } catch (ParseException e) { 86 | // Nothing. 87 | } 88 | } 89 | 90 | if (date == null) return -1L; 91 | return date.getTime(); 92 | } 93 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/util/MultiValueMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.util; 17 | 18 | 19 | import java.util.List; 20 | import java.util.Map; 21 | 22 | /** 23 | * Created by YanZhenjie on 2018/6/21. 24 | */ 25 | public interface MultiValueMap extends Map> { 26 | 27 | /** 28 | * Return the first value for the given key. 29 | * 30 | * @param key the key. 31 | * 32 | * @return the first value for the specified key, or null. 33 | */ 34 | V getFirst(K key); 35 | 36 | /** 37 | * Add the given single value to the current list of values for the given key. 38 | * 39 | * @param key the key. 40 | * @param value the value to be added. 41 | */ 42 | void add(K key, V value); 43 | 44 | /** 45 | * Set the given single value under the given key. 46 | * 47 | * @param key the key. 48 | * @param value the value to set. 49 | */ 50 | void set(K key, V value); 51 | 52 | /** 53 | * Set the given values under. 54 | * 55 | * @param values the values. 56 | */ 57 | void setAll(Map values); 58 | 59 | /** 60 | * Returns the first values contained in this {@code MultiValueMap}. 61 | * 62 | * @return a single value representation of this map. 63 | */ 64 | Map toSingleValueMap(); 65 | 66 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/util/Patterns.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 YanZhenjie. 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 | package com.yanzhenjie.andserver.util; 17 | 18 | /** 19 | * Created by YanZhenjie on 2018/9/5. 20 | */ 21 | public interface Patterns { 22 | 23 | String WORD = "[a-zA-Z0-9_\\-\\.]%s"; 24 | 25 | String PATH_0 = String.format(WORD, "*"); 26 | String PATH_1 = String.format(WORD, "+"); 27 | String PATH = String.format("(/%s)|((/%s)+)", PATH_0, PATH_1); 28 | 29 | String PAIR_KEY = String.format(WORD, "+"); 30 | String PAIR_VALUE = "(.)*"; 31 | String PAIR_KEY_VALUE = String.format("(%s)(=)(%s)", PAIR_KEY, PAIR_VALUE); 32 | String PAIR_NO_KEY = String.format("!%s", PAIR_KEY); 33 | String PAIR_NO_VALUE = String.format("(%s)(!=)(%s)", PAIR_KEY, PATH_1); 34 | 35 | String FORWARD = "forward:(.)*"; 36 | String REDIRECT = "redirect:(.)*"; 37 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/util/TypeWrapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 YanZhenjie. 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 | package com.yanzhenjie.andserver.util; 17 | 18 | import java.lang.reflect.ParameterizedType; 19 | import java.lang.reflect.Type; 20 | 21 | /** 22 | * Created by YanZhenjie on 2018/9/11. 23 | */ 24 | public abstract class TypeWrapper { 25 | 26 | private final Type mType; 27 | 28 | public TypeWrapper() { 29 | Type superClass = getClass().getGenericSuperclass(); 30 | mType = ((ParameterizedType)superClass).getActualTypeArguments()[0]; 31 | } 32 | 33 | public Type getType() { 34 | return mType; 35 | } 36 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/util/UrlCoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.util; 17 | 18 | import java.io.UnsupportedEncodingException; 19 | import java.net.URLDecoder; 20 | import java.net.URLEncoder; 21 | import java.nio.charset.Charset; 22 | 23 | /** 24 | * Created by YanZhenjie on 2018/8/6. 25 | */ 26 | public class UrlCoder { 27 | 28 | public static String urlEncode(String target, String charset) { 29 | try { 30 | return URLEncoder.encode(target, charset); 31 | } catch (UnsupportedEncodingException e) { 32 | return target; 33 | } 34 | } 35 | 36 | public static String urlEncode(String target, Charset charset) { 37 | return urlEncode(target, charset.name()); 38 | } 39 | 40 | public static String urlDecode(String target, String charset) { 41 | try { 42 | return URLDecoder.decode(target, charset); 43 | } catch (UnsupportedEncodingException e) { 44 | return target; 45 | } 46 | } 47 | 48 | public static String urlDecode(String target, Charset charset) { 49 | return urlDecode(target, charset.name()); 50 | } 51 | } -------------------------------------------------------------------------------- /api/src/main/java/com/yanzhenjie/andserver/util/comparator/InvertibleComparator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.yanzhenjie.andserver.util.comparator; 17 | 18 | import com.yanzhenjie.andserver.util.Assert; 19 | 20 | import java.io.Serializable; 21 | import java.util.Comparator; 22 | 23 | /** 24 | * Created by YanZhenjie on 2018/7/11. 25 | */ 26 | public class InvertibleComparator implements Comparator, Serializable { 27 | 28 | private final Comparator comparator; 29 | 30 | private boolean ascending = true; 31 | 32 | /** 33 | * Create an InvertibleComparator that sorts ascending by default. For the actual comparison, the specified 34 | * Comparator will be used. 35 | * 36 | * @param comparator the comparator to decorate. 37 | */ 38 | public InvertibleComparator(Comparator comparator) { 39 | Assert.notNull(comparator, "Comparator must not be null."); 40 | this.comparator = comparator; 41 | } 42 | 43 | /** 44 | * Create an InvertibleComparator that sorts based on the provided order. For the actual comparison, the specified 45 | * Comparator will be used. 46 | * 47 | * @param comparator the comparator to decorate. 48 | * @param ascending the sort order: ascending (true) or descending (false). 49 | */ 50 | public InvertibleComparator(Comparator comparator, boolean ascending) { 51 | Assert.notNull(comparator, "Comparator must not be null."); 52 | this.comparator = comparator; 53 | setAscending(ascending); 54 | } 55 | 56 | /** 57 | * Specify the sort order: ascending (true) or descending (false). 58 | */ 59 | public void setAscending(boolean ascending) { 60 | this.ascending = ascending; 61 | } 62 | 63 | /** 64 | * Return the sort order: ascending (true) or descending (false). 65 | */ 66 | public boolean isAscending() { 67 | return this.ascending; 68 | } 69 | 70 | /** 71 | * Invert the sort order: ascending -> descending or descending -> ascending. 72 | */ 73 | public void invertOrder() { 74 | this.ascending = !this.ascending; 75 | } 76 | 77 | @Override 78 | public int compare(T o1, T o2) { 79 | int result = this.comparator.compare(o1, o2); 80 | if (result != 0) { 81 | // Invert the order if it is a reverse sort. 82 | if (!this.ascending) { 83 | if (Integer.MIN_VALUE == result) { 84 | result = Integer.MAX_VALUE; 85 | } else { 86 | result *= -1; 87 | } 88 | } 89 | return result; 90 | } 91 | return 0; 92 | } 93 | 94 | @SuppressWarnings("unchecked") 95 | @Override 96 | public boolean equals(Object obj) { 97 | if (this == obj) { 98 | return true; 99 | } 100 | if (!(obj instanceof InvertibleComparator)) { 101 | return false; 102 | } 103 | InvertibleComparator other = (InvertibleComparator)obj; 104 | return (this.comparator.equals(other.comparator) && this.ascending == other.ascending); 105 | } 106 | 107 | @Override 108 | public int hashCode() { 109 | return this.comparator.hashCode(); 110 | } 111 | 112 | @Override 113 | public String toString() { 114 | return "InvertibleComparator: [" + this.comparator + "]; ascending=" + this.ascending; 115 | } 116 | } -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 26 5 | defaultConfig { 6 | applicationId "com.tensun.andserver" 7 | minSdkVersion 17 8 | targetSdkVersion 26 9 | versionCode 1 10 | versionName "1.0" 11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | implementation fileTree(dir: 'libs', include: ['*.jar']) 23 | implementation 'com.android.support:appcompat-v7:26.1.0' 24 | implementation 'com.android.support.constraint:constraint-layout:1.1.3' 25 | testImplementation 'junit:junit:4.12' 26 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 27 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 28 | implementation 'com.android.support:design:27.1.1' 29 | 30 | annotationProcessor 'com.yanzhenjie.andserver:processor:2.0.4' 31 | implementation 'com.yanzhenjie:loading:1.0.0' 32 | implementation 'com.alibaba:fastjson:1.1.68.android' 33 | implementation 'org.apache.commons:commons-lang3:3.8.1' 34 | implementation 'org.apache.commons:commons-collections4:4.2' 35 | // implementation 'com.yanzhenjie.andserver:api:2.0.4' 36 | //如果适配机型为Android4.2,请使用下面的库,注释上面的库 37 | implementation project(':api') 38 | 39 | } 40 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/tensun/andserver/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.tensun.andserver; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.tensun.andserver", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/assets/web/css/login.css: -------------------------------------------------------------------------------- 1 | .sec_body { color:#404040;background:#EBEBEB;text-shadow:#ddd 0 1px 0px;font-family:Helvetica;line-height:1.5;font-size:small; } 2 | .center_father {color:#404040;text-align: center;} 3 | .center_son { margin-right: auto; margin-left: auto; } -------------------------------------------------------------------------------- /app/src/main/assets/web/image/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hwx95/AndServer/02cc8c93af9f52edfbfd386af348ab60b857c998/app/src/main/assets/web/image/logo.png -------------------------------------------------------------------------------- /app/src/main/assets/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | AndServer Sample 8 | 11 | 12 | 13 |
14 |
15 | Login

16 | More, please see the sample code. 17 |
18 | 19 | -------------------------------------------------------------------------------- /app/src/main/assets/web/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Sign In 10 | 11 | 12 | 13 |
14 |

Sign In

15 |
16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 38 | 39 |
Account:  
    
Password:  
    
36 | 37 |
40 |

Account: 123, Password: 123

41 |
42 | 43 | 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/tensun/andserver/sample/App.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.tensun.andserver.sample; 17 | 18 | import android.app.Application; 19 | import android.content.Context; 20 | import android.os.Environment; 21 | import android.support.annotation.NonNull; 22 | 23 | import com.tensun.andserver.sample.util.FileUtils; 24 | import com.yanzhenjie.andserver.util.IOUtils; 25 | 26 | import java.io.File; 27 | 28 | /** 29 | * Created by YanZhenjie on 2018/6/9. 30 | */ 31 | public class App extends Application { 32 | 33 | private static App mInstance; 34 | 35 | private File mRootDir; 36 | 37 | @Override 38 | public void onCreate() { 39 | super.onCreate(); 40 | 41 | if (mInstance == null) { 42 | mInstance = this; 43 | initRootPath(this); 44 | } 45 | } 46 | 47 | @NonNull 48 | public static App getInstance() { 49 | return mInstance; 50 | } 51 | 52 | @NonNull 53 | public File getRootDir() { 54 | return mRootDir; 55 | } 56 | 57 | private void initRootPath(Context context) { 58 | if (mRootDir != null) return; 59 | 60 | if (FileUtils.storageAvailable()) { 61 | mRootDir = Environment.getExternalStorageDirectory(); 62 | } else { 63 | mRootDir = context.getFilesDir(); 64 | } 65 | mRootDir = new File(mRootDir, "AndServer"); 66 | IOUtils.createFolder(mRootDir); 67 | } 68 | } -------------------------------------------------------------------------------- /app/src/main/java/com/tensun/andserver/sample/CoreService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 Yan Zhenjie. 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 | package com.tensun.andserver.sample; 17 | 18 | import android.app.Service; 19 | import android.content.Intent; 20 | import android.os.IBinder; 21 | import android.support.annotation.Nullable; 22 | 23 | import com.tensun.andserver.sample.util.NetUtils; 24 | import com.yanzhenjie.andserver.AndServer; 25 | import com.yanzhenjie.andserver.Server; 26 | 27 | import java.util.concurrent.TimeUnit; 28 | 29 | /** 30 | * Created by Yan Zhenjie on 2018/6/9. 31 | */ 32 | public class CoreService extends Service { 33 | 34 | private Server mServer; 35 | 36 | @Override 37 | public void onCreate() { 38 | mServer = AndServer.serverBuilder() 39 | .inetAddress(NetUtils.getLocalIPAddress()) 40 | .port(8080) 41 | .timeout(10, TimeUnit.SECONDS) 42 | .listener(new Server.ServerListener() { 43 | @Override 44 | public void onStarted() { 45 | String hostAddress = mServer.getInetAddress().getHostAddress(); 46 | ServerManager.onServerStart(CoreService.this, hostAddress); 47 | } 48 | 49 | @Override 50 | public void onStopped() { 51 | ServerManager.onServerStop(CoreService.this); 52 | } 53 | 54 | @Override 55 | public void onException(Exception e) { 56 | ServerManager.onServerError(CoreService.this, e.getMessage()); 57 | } 58 | }) 59 | .build(); 60 | } 61 | 62 | @Override 63 | public int onStartCommand(Intent intent, int flags, int startId) { 64 | startServer(); 65 | return START_STICKY; 66 | } 67 | 68 | @Override 69 | public void onDestroy() { 70 | stopServer(); 71 | super.onDestroy(); 72 | } 73 | 74 | /** 75 | * Start server. 76 | */ 77 | private void startServer() { 78 | if (mServer.isRunning()) { 79 | String hostAddress = mServer.getInetAddress().getHostAddress(); 80 | ServerManager.onServerStart(CoreService.this, hostAddress); 81 | } else { 82 | mServer.startup(); 83 | } 84 | } 85 | 86 | /** 87 | * Stop server. 88 | */ 89 | private void stopServer() { 90 | mServer.shutdown(); 91 | } 92 | 93 | @Nullable 94 | @Override 95 | public IBinder onBind(Intent intent) { 96 | return null; 97 | } 98 | } -------------------------------------------------------------------------------- /app/src/main/java/com/tensun/andserver/sample/component/AppExceptionResolver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.tensun.andserver.sample.component; 17 | 18 | import android.support.annotation.NonNull; 19 | 20 | import com.tensun.andserver.sample.util.JsonUtils; 21 | import com.yanzhenjie.andserver.annotation.Resolver; 22 | import com.yanzhenjie.andserver.error.BasicException; 23 | import com.yanzhenjie.andserver.framework.ExceptionResolver; 24 | import com.yanzhenjie.andserver.framework.body.JsonBody; 25 | import com.yanzhenjie.andserver.http.HttpRequest; 26 | import com.yanzhenjie.andserver.http.HttpResponse; 27 | import com.yanzhenjie.andserver.util.StatusCode; 28 | 29 | /** 30 | * Created by YanZhenjie on 2018/9/11. 31 | */ 32 | @Resolver 33 | public class AppExceptionResolver implements ExceptionResolver { 34 | 35 | @Override 36 | public void onResolve(@NonNull HttpRequest request, @NonNull HttpResponse response, @NonNull Throwable e) { 37 | e.printStackTrace(); 38 | if (e instanceof BasicException) { 39 | BasicException exception = (BasicException)e; 40 | response.setStatus(exception.getStatusCode()); 41 | } else { 42 | response.setStatus(StatusCode.SC_INTERNAL_SERVER_ERROR); 43 | } 44 | String body = JsonUtils.failedJson(response.getStatus(), e.getMessage()); 45 | response.setBody(new JsonBody(body)); 46 | } 47 | } -------------------------------------------------------------------------------- /app/src/main/java/com/tensun/andserver/sample/component/AppMessageConverter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.tensun.andserver.sample.component; 17 | 18 | import android.support.annotation.NonNull; 19 | import android.support.annotation.Nullable; 20 | 21 | import com.tensun.andserver.sample.util.JsonUtils; 22 | import com.yanzhenjie.andserver.annotation.Converter; 23 | import com.yanzhenjie.andserver.framework.MessageConverter; 24 | import com.yanzhenjie.andserver.framework.body.JsonBody; 25 | import com.yanzhenjie.andserver.http.ResponseBody; 26 | import com.yanzhenjie.andserver.util.IOUtils; 27 | import com.yanzhenjie.andserver.util.MediaType; 28 | 29 | import java.io.IOException; 30 | import java.io.InputStream; 31 | import java.lang.reflect.Type; 32 | import java.nio.charset.Charset; 33 | 34 | /** 35 | * Created by YanZhenjie on 2018/9/11. 36 | */ 37 | @Converter 38 | public class AppMessageConverter implements MessageConverter { 39 | 40 | @Override 41 | public ResponseBody convert(@NonNull Object output, @Nullable MediaType mediaType) { 42 | return new JsonBody(JsonUtils.successfulJson(output)); 43 | } 44 | 45 | @Nullable 46 | @Override 47 | public T convert(@NonNull InputStream stream, @Nullable MediaType mediaType, Type type) throws IOException { 48 | Charset charset = mediaType == null ? null : mediaType.getCharset(); 49 | if (charset == null) { 50 | return JsonUtils.parseJson(IOUtils.toString(stream), type); 51 | } 52 | return JsonUtils.parseJson(IOUtils.toString(stream, charset), type); 53 | } 54 | } -------------------------------------------------------------------------------- /app/src/main/java/com/tensun/andserver/sample/component/InternalWebsite.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.tensun.andserver.sample.component; 17 | 18 | import com.yanzhenjie.andserver.annotation.Website; 19 | import com.yanzhenjie.andserver.framework.website.AssetsWebsite; 20 | 21 | /** 22 | * Created by YanZhenjie on 2018/9/17. 23 | */ 24 | @Website 25 | public class InternalWebsite extends AssetsWebsite { 26 | 27 | public InternalWebsite() { 28 | super("/web"); 29 | } 30 | } -------------------------------------------------------------------------------- /app/src/main/java/com/tensun/andserver/sample/component/LoggerInterceptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.tensun.andserver.sample.component; 17 | 18 | import android.support.annotation.NonNull; 19 | 20 | import com.tensun.andserver.sample.util.JsonUtils; 21 | import com.tensun.andserver.sample.util.Logger; 22 | import com.yanzhenjie.andserver.annotation.Interceptor; 23 | import com.yanzhenjie.andserver.framework.HandlerInterceptor; 24 | import com.yanzhenjie.andserver.framework.handler.RequestHandler; 25 | import com.yanzhenjie.andserver.http.HttpMethod; 26 | import com.yanzhenjie.andserver.http.HttpRequest; 27 | import com.yanzhenjie.andserver.http.HttpResponse; 28 | import com.yanzhenjie.andserver.util.MultiValueMap; 29 | 30 | /** 31 | * Created by YanZhenjie on 2018/9/11. 32 | */ 33 | @Interceptor 34 | public class LoggerInterceptor implements HandlerInterceptor { 35 | 36 | @Override 37 | public boolean onIntercept(@NonNull HttpRequest request, @NonNull HttpResponse response, 38 | @NonNull RequestHandler handler) { 39 | String path = request.getPath(); 40 | HttpMethod method = request.getMethod(); 41 | MultiValueMap valueMap = request.getParameter(); 42 | Logger.i("Path: " + path); 43 | Logger.i("Method: " + method.value()); 44 | Logger.i("Param: " + JsonUtils.toJsonString(valueMap)); 45 | return false; 46 | } 47 | } -------------------------------------------------------------------------------- /app/src/main/java/com/tensun/andserver/sample/component/LoginInterceptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.tensun.andserver.sample.component; 17 | 18 | import android.support.annotation.NonNull; 19 | 20 | import com.yanzhenjie.andserver.annotation.Interceptor; 21 | import com.yanzhenjie.andserver.error.BasicException; 22 | import com.yanzhenjie.andserver.framework.HandlerInterceptor; 23 | import com.yanzhenjie.andserver.framework.handler.MethodHandler; 24 | import com.yanzhenjie.andserver.framework.handler.RequestHandler; 25 | import com.yanzhenjie.andserver.http.HttpRequest; 26 | import com.yanzhenjie.andserver.http.HttpResponse; 27 | import com.yanzhenjie.andserver.http.session.Session; 28 | import com.yanzhenjie.andserver.mapping.Addition; 29 | 30 | import org.apache.commons.lang3.ArrayUtils; 31 | 32 | /** 33 | * Created by YanZhenjie on 2018/9/11. 34 | */ 35 | @Interceptor 36 | public class LoginInterceptor implements HandlerInterceptor { 37 | 38 | public static final String LOGIN_ATTRIBUTE = "USER.LOGIN.SIGN"; 39 | 40 | @Override 41 | public boolean onIntercept(@NonNull HttpRequest request, @NonNull HttpResponse response, 42 | @NonNull RequestHandler handler) { 43 | if (handler instanceof MethodHandler) { 44 | MethodHandler methodHandler = (MethodHandler)handler; 45 | Addition addition = methodHandler.getAddition(); 46 | if (!isLogin(request, addition)) { 47 | throw new BasicException(401, "You are not logged in yet."); 48 | } 49 | } 50 | return false; 51 | } 52 | 53 | private boolean isNeedLogin(Addition addition) { 54 | if (addition == null) return false; 55 | 56 | String[] stringType = addition.getStringType(); 57 | if (ArrayUtils.isEmpty(stringType)) return false; 58 | 59 | boolean[] booleanType = addition.getBooleanType(); 60 | if (ArrayUtils.isEmpty(booleanType)) return false; 61 | return stringType[0].equalsIgnoreCase("login") && booleanType[0]; 62 | } 63 | 64 | private boolean isLogin(HttpRequest request, Addition addition) { 65 | if (isNeedLogin(addition)) { 66 | Session session = request.getSession(); 67 | if (session != null) { 68 | Object o = session.getAttribute(LOGIN_ATTRIBUTE); 69 | return o != null && (o instanceof Boolean) && ((boolean)o); 70 | } 71 | return false; 72 | } 73 | return true; 74 | } 75 | } -------------------------------------------------------------------------------- /app/src/main/java/com/tensun/andserver/sample/controller/PageController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.tensun.andserver.sample.controller; 17 | 18 | import com.yanzhenjie.andserver.annotation.Controller; 19 | import com.yanzhenjie.andserver.annotation.GetMapping; 20 | 21 | /** 22 | * Created by YanZhenjie on 2018/9/12. 23 | */ 24 | @Controller 25 | public class PageController { 26 | 27 | @GetMapping(path = "/") 28 | public String index() { 29 | // Equivalent to [return "/index"]. 30 | return "forward:/index.html"; 31 | } 32 | } -------------------------------------------------------------------------------- /app/src/main/java/com/tensun/andserver/sample/model/ReturnData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.tensun.andserver.sample.model; 17 | 18 | import android.os.Parcel; 19 | import android.os.Parcelable; 20 | 21 | import com.alibaba.fastjson.annotation.JSONField; 22 | 23 | /** 24 | * Created by YanZhenjie on 2018/6/9. 25 | */ 26 | public class ReturnData implements Parcelable { 27 | 28 | @JSONField(name = "isSuccess") 29 | private boolean isSuccess; 30 | 31 | @JSONField(name = "errorCode") 32 | private int errorCode; 33 | 34 | @JSONField(name = "errorMsg") 35 | private String errorMsg; 36 | 37 | @JSONField(name = "data") 38 | private Object data; 39 | 40 | public ReturnData() { 41 | } 42 | 43 | protected ReturnData(Parcel in) { 44 | isSuccess = in.readByte() != 0; 45 | errorCode = in.readInt(); 46 | errorMsg = in.readString(); 47 | } 48 | 49 | @Override 50 | public void writeToParcel(Parcel dest, int flags) { 51 | dest.writeByte((byte)(isSuccess ? 1 : 0)); 52 | dest.writeInt(errorCode); 53 | dest.writeString(errorMsg); 54 | } 55 | 56 | @Override 57 | public int describeContents() { 58 | return 0; 59 | } 60 | 61 | public static final Creator CREATOR = new Creator() { 62 | @Override 63 | public ReturnData createFromParcel(Parcel in) { 64 | return new ReturnData(in); 65 | } 66 | 67 | @Override 68 | public ReturnData[] newArray(int size) { 69 | return new ReturnData[size]; 70 | } 71 | }; 72 | 73 | public boolean isSuccess() { 74 | return isSuccess; 75 | } 76 | 77 | public void setSuccess(boolean success) { 78 | isSuccess = success; 79 | } 80 | 81 | public int getErrorCode() { 82 | return errorCode; 83 | } 84 | 85 | public void setErrorCode(int errorCode) { 86 | this.errorCode = errorCode; 87 | } 88 | 89 | public String getErrorMsg() { 90 | return errorMsg; 91 | } 92 | 93 | public void setErrorMsg(String errorMsg) { 94 | this.errorMsg = errorMsg; 95 | } 96 | 97 | public Object getData() { 98 | return data; 99 | } 100 | 101 | public void setData(Object data) { 102 | this.data = data; 103 | } 104 | } -------------------------------------------------------------------------------- /app/src/main/java/com/tensun/andserver/sample/model/UserInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.tensun.andserver.sample.model; 17 | 18 | import android.os.Parcel; 19 | import android.os.Parcelable; 20 | 21 | import com.alibaba.fastjson.annotation.JSONField; 22 | 23 | /** 24 | * Created by YanZhenjie on 2018/6/9. 25 | */ 26 | public class UserInfo implements Parcelable { 27 | 28 | @JSONField(name = "userId") 29 | private String mUserId; 30 | @JSONField(name = "userName") 31 | private String mUserName; 32 | 33 | public UserInfo() { 34 | } 35 | 36 | protected UserInfo(Parcel in) { 37 | mUserId = in.readString(); 38 | mUserName = in.readString(); 39 | } 40 | 41 | @Override 42 | public void writeToParcel(Parcel dest, int flags) { 43 | dest.writeString(mUserId); 44 | dest.writeString(mUserName); 45 | } 46 | 47 | @Override 48 | public int describeContents() { 49 | return 0; 50 | } 51 | 52 | public static final Creator CREATOR = new Creator() { 53 | @Override 54 | public UserInfo createFromParcel(Parcel in) { 55 | return new UserInfo(in); 56 | } 57 | 58 | @Override 59 | public UserInfo[] newArray(int size) { 60 | return new UserInfo[size]; 61 | } 62 | }; 63 | 64 | public String getUserId() { 65 | return mUserId; 66 | } 67 | 68 | public void setUserId(String userId) { 69 | mUserId = userId; 70 | } 71 | 72 | public String getUserName() { 73 | return mUserName; 74 | } 75 | 76 | public void setUserName(String userName) { 77 | this.mUserName = userName; 78 | } 79 | } -------------------------------------------------------------------------------- /app/src/main/java/com/tensun/andserver/sample/util/FileUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.tensun.andserver.sample.util; 17 | 18 | import android.os.Environment; 19 | import android.webkit.MimeTypeMap; 20 | 21 | import com.tensun.andserver.sample.App; 22 | import com.yanzhenjie.andserver.http.multipart.MultipartFile; 23 | import com.yanzhenjie.andserver.util.StringUtils; 24 | 25 | import java.io.File; 26 | import java.util.UUID; 27 | 28 | /** 29 | * Created by YanZhenjie on 2018/6/9. 30 | */ 31 | public class FileUtils { 32 | 33 | /** 34 | * Create a random file based on mimeType. 35 | * 36 | * @param file file. 37 | * 38 | * @return file object. 39 | */ 40 | public static File createRandomFile(MultipartFile file) { 41 | String extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(file.getContentType().toString()); 42 | if (StringUtils.isEmpty(extension)) { 43 | extension = MimeTypeMap.getFileExtensionFromUrl(file.getFilename()); 44 | } 45 | String uuid = UUID.randomUUID().toString(); 46 | return new File(App.getInstance().getRootDir(), uuid + "." + extension); 47 | } 48 | 49 | /** 50 | * SD is available. 51 | * 52 | * @return true, otherwise is false. 53 | */ 54 | public static boolean storageAvailable() { 55 | if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { 56 | File sd = new File(Environment.getExternalStorageDirectory().getAbsolutePath()); 57 | return sd.canWrite(); 58 | } else { 59 | return false; 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /app/src/main/java/com/tensun/andserver/sample/util/JsonUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 YanZhenjie. 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 | package com.tensun.andserver.sample.util; 17 | 18 | import com.alibaba.fastjson.JSON; 19 | import com.tensun.andserver.sample.model.ReturnData; 20 | 21 | import java.lang.reflect.Type; 22 | 23 | /** 24 | * Created by YanZhenjie on 2018/6/9. 25 | */ 26 | public class JsonUtils { 27 | 28 | /** 29 | * Business is successful. 30 | * 31 | * @param data return data. 32 | * 33 | * @return json. 34 | */ 35 | public static String successfulJson(Object data) { 36 | ReturnData returnData = new ReturnData(); 37 | returnData.setSuccess(true); 38 | returnData.setErrorCode(200); 39 | returnData.setData(data); 40 | return JSON.toJSONString(returnData); 41 | } 42 | 43 | /** 44 | * Business is failed. 45 | * 46 | * @param code error code. 47 | * @param message message. 48 | * 49 | * @return json. 50 | */ 51 | public static String failedJson(int code, String message) { 52 | ReturnData returnData = new ReturnData(); 53 | returnData.setSuccess(false); 54 | returnData.setErrorCode(code); 55 | returnData.setErrorMsg(message); 56 | return JSON.toJSONString(returnData); 57 | } 58 | 59 | /** 60 | * Converter object to json string. 61 | * 62 | * @param data the object. 63 | * 64 | * @return json string. 65 | */ 66 | public static String toJsonString(Object data) { 67 | return JSON.toJSONString(data); 68 | } 69 | 70 | /** 71 | * Parse json to object. 72 | * 73 | * @param json json string. 74 | * @param type the type of object. 75 | * @param type. 76 | * 77 | * @return object. 78 | */ 79 | public static T parseJson(String json, Type type) { 80 | return JSON.parseObject(json, type); 81 | } 82 | } -------------------------------------------------------------------------------- /app/src/main/java/com/tensun/andserver/sample/util/Logger.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Yan Zhenjie. 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 | package com.tensun.andserver.sample.util; 17 | 18 | import android.util.Log; 19 | 20 | /** 21 | * Created by YanZhenjie on 2018/9/12. 22 | */ 23 | public class Logger { 24 | 25 | private static final String TAG = "AndServerSample"; 26 | private static final boolean DEBUG = true; 27 | 28 | public static void i(Object obj) { 29 | if (DEBUG) { 30 | Log.i(TAG, obj == null ? "null" : obj.toString()); 31 | } 32 | } 33 | 34 | public static void d(Object obj) { 35 | if (DEBUG) { 36 | Log.d(TAG, obj == null ? "null" : obj.toString()); 37 | } 38 | } 39 | 40 | public static void v(Object obj) { 41 | if (DEBUG) { 42 | Log.v(TAG, obj == null ? "null" : obj.toString()); 43 | } 44 | } 45 | 46 | public static void w(Object obj) { 47 | if (DEBUG) { 48 | Log.w(TAG, obj == null ? "null" : obj.toString()); 49 | } 50 | } 51 | 52 | public static void e(Object obj) { 53 | if (DEBUG) { 54 | Log.e(TAG, obj == null ? "null" : obj.toString()); 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /app/src/main/java/com/tensun/andserver/sample/util/NetUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2018 Yan Zhenjie. 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 | package com.tensun.andserver.sample.util; 17 | 18 | import java.net.InetAddress; 19 | import java.net.NetworkInterface; 20 | import java.net.SocketException; 21 | import java.util.Enumeration; 22 | import java.util.regex.Pattern; 23 | 24 | /** 25 | * Created by YanZhenjie on 2018/6/9. 26 | */ 27 | public class NetUtils { 28 | 29 | /** 30 | * Ipv4 address check. 31 | */ 32 | private static final Pattern IPV4_PATTERN = Pattern.compile( 33 | "^(" + "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}" + 34 | "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"); 35 | 36 | /** 37 | * Check if valid IPV4 address. 38 | * 39 | * @param input the address string to check for validity. 40 | * 41 | * @return True if the input parameter is a valid IPv4 address. 42 | */ 43 | public static boolean isIPv4Address(String input) { 44 | return IPV4_PATTERN.matcher(input).matches(); 45 | } 46 | 47 | /** 48 | * Get local Ip address. 49 | */ 50 | public static InetAddress getLocalIPAddress() { 51 | Enumeration enumeration = null; 52 | try { 53 | enumeration = NetworkInterface.getNetworkInterfaces(); 54 | } catch (SocketException e) { 55 | e.printStackTrace(); 56 | } 57 | if (enumeration != null) { 58 | while (enumeration.hasMoreElements()) { 59 | NetworkInterface nif = enumeration.nextElement(); 60 | Enumeration inetAddresses = nif.getInetAddresses(); 61 | if (inetAddresses != null) { 62 | while (inetAddresses.hasMoreElements()) { 63 | InetAddress inetAddress = inetAddresses.nextElement(); 64 | if (!inetAddress.isLoopbackAddress() && isIPv4Address(inetAddress.getHostAddress())) { 65 | return inetAddress; 66 | } 67 | } 68 | } 69 | } 70 | } 71 | return null; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 23 | 24 | 28 | 29 | 36 | 37 | 38 | 39 | 45 | 46 |