Android AndServer本地服务器
1.AndServer简介
官方文档:https://github.com/yanzhenjie/AndServer
AndServer 是一个 HTTP 和反向代理服务器。Android平台的Web服务器和Web框架。它提供了像SpringMVC一样的注解,如果你熟悉SpringMVC,你可以很快掌握它。
1.web网站部署。
2.动态http api部署。
3.反向代理服务器。
2.AndServer使用
1.项目使用依赖添加
App目录 build.gradle,如果您使用的是 Kotlin,请替换annotationProcessor为kapt.
plugins { id 'com.android.application' } apply plugin: 'com.yanzhenjie.andserver'...
...
dependencies { implementation 'com.yanzhenjie.andserver:api:2.1.12' annotationProcessor 'com.yanzhenjie.andserver:processor:2.1.12' }
project build.gradle中
buildscript {
dependencies {
classpath 'com.yanzhenjie.andserver:plugin:2.1.12'
}
}
2. web网站部署。
web项目文件位置设置,比如vue3,导出dist文件,并放在如下位置,并在AppConfig中配置该位置目录。

@Config
public class AppConfig implements WebConfig {
@Override
public void onConfig(Context context, Delegate delegate) {
// 增加一个位于assets的web目录的网站
delegate.addWebsite(new AssetsWebsite(context, "/dist/"));
// 增加一个位于/sdcard/Download/AndServer/目录的网站
// delegate.addWebsite(new StorageWebsite(context, "/sdcard/Download/AndServer/"));
}
}
新建Web服务,并开启
若不适用inetAddress设置地址,则Android ip改变后,服务器ip也会随之改变,能更好的适配网络的变动。
Server mServer = AndServer.webServer(context) // .inetAddress(add.getAddress()) .port(33333) .timeout(10, TimeUnit.SECONDS) .listener(new Server.ServerListener() { @Override public void onStarted() { Log.e(TAG,"onStarted"+mServer.getInetAddress()); } @Override public void onStopped() { Log.e(TAG,"onStopped"); } @Override public void onException(Exception e) { Log.e(TAG,"onException"+e.getMessage()); } }) .build();mServer.startup();//开启服务mServer.shutdown();//关闭服务
3.动态http api部署
部署服务器
它还具有一些功能,例如inetAddress(InetAddress)、serverSocketFactory(ServerSocketFactory)和sslContext(SSLContext),具体取决于您想要实现的目标。
Server server = AndServer.webServer(context)
.port(8080)
.timeout(10, TimeUnit.SECONDS)
.build();
// startup the server.
server.startup();
...
// shutdown the server.
server.shutdown();
生成HTTP API
POST http://.../user/login
GET http://.../user/uid_001?fields=id,name,age
PUT http://.../user/uid_001
@RestController
@RequestMapping(path = "/user")
public class UserController {
@PostMapping("/login")
public String login(@RequestParam("account") String account,
@RequestParam("password") String password) {
...
return "Successful.";
}
@GetMapping(path = "/{userId}")
public User info(@PathVariable("userId") String userId,
@QueryParam("fields") String fields) {
User user = findUserById(userId, fields);
...
return user;
}
@PutMapping(path = "/{userId}")
public void modify(@PathVariable("userId") String userId
@RequestParam("age") int age) {
...
}
}
文件上传
@RestController
@RequestMapping(path = "/user")
public class ServerController {
private String TAG = "ServerController";
@CrossOrigin(methods = {RequestMethod.POST, RequestMethod.GET})
@PostMapping(path = "/upload", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
String upload(@RequestParam(name = "file") final MultipartFile file, @RequestParam(name = "single_file_name") String fileName) {
StandardMultipartFile multipartFile= (StandardMultipartFile) file;
Log.i(TAG,"文件名:"+fileName);
//直接对临时文件重命名,不进行复制操作
DiskFileItem fileItem = (DiskFileItem) multipartFile.getFileItem();
String name = fileItem.getName();
if(name.indexOf(".")>0){
name= name.replace(".", "_" + System.currentTimeMillis() + ".");
}else{
name=name+"_"+System.currentTimeMillis();
}
UploadFileInfo uploadFileInfo=new UploadFileInfo();
try {
if(fileItem.isInMemory()){
File dest = new File(Constants.UPLOAD_CACHE_FOLDER, name);
file.transferTo(dest);
uploadFileInfo.setFilePath(dest.getAbsolutePath());
}else{
Path sourcePath=Paths.get(fileItem.getStoreLocation().getAbsolutePath());
Path renamedPath = Paths.get(sourcePath.getParent().toString(),name);
Files.move(sourcePath,renamedPath);
uploadFileInfo.setFilePath(renamedPath.toString());
}
uploadFileInfo.setFileName(name);
uploadFileInfo.setUploadProgress(100);
Log.i(TAG,Thread.currentThread().getName());
// We use a sub-thread to process files so that the api '/upload' can respond faster
RxBus.get().post(BusAction.ADD_UPLOAD_FILE,uploadFileInfo);
} catch (IOException e) {
e.printStackTrace();
}
return uploadFileInfo.getFilePath();
}
@CrossOrigin(methods = {RequestMethod.POST, RequestMethod.GET})
@PostMapping(path = "/upload/count", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
boolean uploadCount(@RequestParam(name = "upload_count") final Integer count) {
Log.i(TAG,"uploadCount:"+count);
RxBus.get().post(BusAction.ADD_UPLOAD_NUMBER,count);
return true;
}@GetMapping("/login")
public String login() {
Log.e(TAG,"login---");
return "HelloWord";
}
}
3.反向代理服务器
Server server = AndServer.proxyServer()
.addProxy("www.example1.com", "http://192.167.1.11:8080")
.addProxy("example2.com", "https://192.167.1.12:9090")
.addProxy("55.66.11.11", "http://www.google.com")
.addProxy("192.168.1.11", "https://github.com:6666")
.port(80)
.timeout(10, TimeUnit.SECONDS)
.build();
// startup the server.
server.startup();
// shutdown the server.
server.shutdown();