Android设备搭建http服务器AndServer
(1)需要在项目中引用AndServer,但是这里面有一些问题,主要是因为新版Android studio中的高版本gradle改变了添加plug和引用的方式。
在项目的根build.gradle文件(不是app那个moudle的build.gradle)最顶部添加:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.yanzhenjie.andserver:plugin:2.1.10'
}
}
(2)然后在当前的moudle(一般就是app)的build.gradle里面的plugins里面添加:id 'com.yanzhenjie.andserver'
然后plugins变成
plugins {
id 'com.android.application'
id 'com.yanzhenjie.andserver'
}
接着在当前的这个build.gradle里面dependencies的添加:
implementation 'com.yanzhenjie.andserver:api:2.1.10'
annotationProcessor 'com.yanzhenjie.andserver:processor:2.1.10'
(3)开始写上层Java代码:
package zhangphil.httpserver;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import com.yanzhenjie.andserver.AndServer;
import com.yanzhenjie.andserver.Server;
import java.util.concurrent.TimeUnit;
public class MainActivity extends AppCompatActivity {
private Server mServer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mServer = AndServer.webServer(this)
.port(9999)
.timeout(10, TimeUnit.SECONDS).listener(new Server.ServerListener() {
@Override
public void onStarted() {
System.out.println("服务器绑定地址:"+NetUtils.getLocalIPAddress().getHostAddress());
}
@Override
public void onStopped() {
}
@Override
public void onException(Exception e) {
}
})
.build();
mServer.startup();
}
@Override
protected void onDestroy() {
super.onDestroy();
mServer.shutdown();
}
}
上面代码主要是启动在Android手机(设备)上的http服务器,服务器绑定端口9999,绑定成功后打印IP地址。
下面是spring样式的restful代码实现,核心关键,http访问接口实现:
package zhangphil.httpserver;
import com.yanzhenjie.andserver.annotation.GetMapping;
import com.yanzhenjie.andserver.annotation.PathVariable;
import com.yanzhenjie.andserver.annotation.PostMapping;
import com.yanzhenjie.andserver.annotation.QueryParam;
import com.yanzhenjie.andserver.annotation.RequestBody;
import com.yanzhenjie.andserver.annotation.RequestParam;
import com.yanzhenjie.andserver.annotation.RestController;
import org.json.JSONObject;
@RestController
public class ServerController {
@GetMapping("/")
public String ping() {
return "SERVER OK";
}
@PostMapping("/user/login")
public JSONObject login(@RequestBody String str) throws Exception {
JSONObject jsonObject = new JSONObject(str);
return jsonObject;
}
@GetMapping("/user/item")
public JSONObject requestItem(@RequestParam("name") String name,
@RequestParam("id") String id) throws Exception {
JSONObject jsonObject = new JSONObject();
jsonObject.put("name", name);
jsonObject.put("id", id);
return jsonObject;
}
@GetMapping("/user/{userId}")
public JSONObject getUser(@PathVariable("userId") String userId,
@QueryParam("key") String key) throws Exception{
JSONObject user = new JSONObject();
user.put("id", userId);
user.put("key", key);
user.put("year", 2022);
return user;
}
}
NetUtils.java主要是为了获取当前Android手机的IP地址:
package zhangphil.httpserver;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import java.util.regex.Pattern;
public class NetUtils {
private static final Pattern IPV4_PATTERN = Pattern.compile(
"^(" + "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}" +
"([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$");
public static boolean isIPv4Address(String input) {
return IPV4_PATTERN.matcher(input).matches();
}
public static InetAddress getLocalIPAddress() {
Enumeration<NetworkInterface> enumeration = null;
try {
enumeration = NetworkInterface.getNetworkInterfaces();
} catch (SocketException e) {
e.printStackTrace();
}
if (enumeration != null) {
while (enumeration.hasMoreElements()) {
NetworkInterface nif = enumeration.nextElement();
Enumeration<InetAddress> inetAddresses = nif.getInetAddresses();
if (inetAddresses != null) {
while (inetAddresses.hasMoreElements()) {
InetAddress inetAddress = inetAddresses.nextElement();
if (!inetAddress.isLoopbackAddress() && isIPv4Address(inetAddress.getHostAddress())) {
return inetAddress;
}
}
}
}
}
return null;
}
}
以上代码写好后,注意在AndroidManifest.xml配置网络权限:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
接下来,就可以通过浏览器或者postman访问Android手机上运行的服务器了。
在浏览器里面测试服务器的连通性,ping()接口:
用户的登陆接口user/login,login()接口:
支持连接符号&的requestItem接口:
具备查询功能的getUser()接口: