首先是安卓客户端界面:
布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<EditText
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="60dp"
android:hint="请输入用户名">
</EditText>
<EditText
android:id="@+id/pwd"
android:layout_width="match_parent"
android:layout_height="60dp"
android:hint="请输入密码">
</EditText>
<Button
android:id="@+id/btn2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="登陆">
</Button>
</LinearLayout>
安卓客户端代码:
package com.example.tomcat;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity {
private Handler handler;
private String TAG="TOMCAT1";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn2=findViewById(R.id.btn2);
btn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
post();
Han();
}
});
}
public void post(){
Thread thread=new Thread(new Runnable() {
@Override
public void run() {
EditText username=findViewById(R.id.username);
EditText pwd=findViewById(R.id.pwd);
OkHttpClient client=new OkHttpClient();
RequestBody requestBody=new FormBody.Builder()
.add("a",username.getText().toString())
.add("b",pwd.getText().toString())
.build();
Request request=new Request.Builder().url("http://192.168.1.2:8080/book/androidpost").post(requestBody).build();
try {
Response response=client.newCall(request).execute();
String responseData2=response.body().string();
Log.d(TAG, responseData2);
Message message=Message.obtain();
message.what=2;
message.obj=responseData2;
handler.sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
}
}
});
thread.start();
}
@SuppressLint("HandlerLeak")
public void Han(){
handler=new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if(msg.what==2){
String str= (String) msg.obj;
if (str.equals("成功")){
Toast.makeText(MainActivity.this, "登陆成功", Toast.LENGTH_SHORT).show();
}
else if(str.equals("失败")){
Toast.makeText(MainActivity.this, "密码错误", Toast.LENGTH_SHORT).show();
}
}
}
};
}
}
注意:因为要与本机的tomcat交互,所以需要在manifest中声明网络权限,这里有个小问题,如果你一开始没有声明网络权限,直接在模拟器运行了安卓程序,后来再加权限重新运行时会提示仍然无法连接,此时需要将App卸载后重新运行重装,还有就是本地Tomcat的url地址是根据cmd查出的ipv4地址再加后缀,我这里是192.168.1.2,我这里用的是虚拟机连接,真机还没试,还有一点由于本机tomcat只能在http协议下访问,而安卓使用的okhttp是无法访问http协议的,所以需要在res下新建一个xml文件夹,新建一个network.xml的配置文件,然后再在manifest中的application标签下添加:android:networkSecurityConfig="@xml/network"
即可使用okhttp访问http协议的url
network.xml:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true"/>
</network-security-config>
manifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.tomcat">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:networkSecurityConfig="@xml/network">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
服务器端由于我是在一个完整的ssm框架的项目上添加的小实验,所以只提供相关的Controller的代码,因为是小实验所以我没有去匹配数据库,而是写死了账号和密码
以下为服务器端:
@RequestMapping(value = "/androidpost",method = RequestMethod.POST)
public void post(HttpServletRequest request, HttpServletResponse response,Model model) throws IOException {
String a=request.getParameter("a");
String b=request.getParameter("b");
System.out.println(a);
System.out.println(b);
response.setContentType("text/html;charset=utf-8");//要先设置字符集
PrintWriter out = response.getWriter();//获取writer
if(a.equals("admin") & b.equals("123456")) {
out.write("成功");//写入,这边写完后,因为本函数是void类型,所以在客户端直接获取response.body.string的内容即成功两个字
}
else {
out.write("失败");
}
out.flush();
out.close();
}
解释下:
根据request.getParameter获得安卓客户端对应的key的值,由于安卓端要通过返回的response.body进而判断登陆的条件,所以在服务器端先为response设置字符集,然后使用printwriter的write方法写入判断用数据,写入后,返回的response.body的内容即write方法写入的内容,这里一定要先设置字符集,否则你write方法写入的如果是中文那会出现问号(?)问题
运行截图: