0. 引言
还是那个老项目,在安卓设备中获得数据,当时后端觉得方便直接在后端中讲数据写在了session中,想着试试在Android中会不会应为跨域问题导致cookie不一致导致数据无法持久化,果真一试发现每次提交的Cookie值都不一样。
1. 项目依赖
在build.gradle.kts中导入下列依赖:
1 2
| implementation("com.squareup.okhttp3:okhttp:4.9.0") implementation ("com.google.code.gson:gson:2.8.8")
|
2. 持久化Cookie
直接将下面的实现类导入即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| package com.example.getsession;
import okhttp3.Cookie; import okhttp3.CookieJar; import okhttp3.HttpUrl;
import java.util.List; import java.util.concurrent.CopyOnWriteArrayList;
public class MyCookieJar implements CookieJar { private final List<Cookie> cookies = new CopyOnWriteArrayList<>();
@Override public void saveFromResponse(HttpUrl url, List<Cookie> cookies) { this.cookies.clear(); this.cookies.addAll(cookies); }
@Override public List<Cookie> loadForRequest(HttpUrl url) { return cookies; } }
|
3. 访问实现
3.1 layout数据展示
随意编写一个能将获取的session展示出来的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="16dp">
<Button android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/login" android:text="登录" android:layout_marginBottom="20dp" />
<TextView android:id="@+id/returnTextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="登录返回信息将显示在这里" android:textSize="18sp" android:layout_marginBottom="20dp" />
<Button android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/getsession" android:text="获取 Session" />
<TextView android:id="@+id/sessionTextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Session 数据将显示在这里" android:textSize="18sp" android:layout_marginTop="20dp" /> </LinearLayout>
|
3.2 获取实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
| package com.example.getsession;
import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import okhttp3.Call; import okhttp3.Callback; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; import okhttp3.FormBody;
import java.io.IOException;
public class MainActivity extends AppCompatActivity { private OkHttpClient client; private TextView returnTextView, sessionTextView; private Button loginButton, getSessionButton;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); MyCookieJar cookieJar = new MyCookieJar(); loginButton = findViewById(R.id.login); getSessionButton = findViewById(R.id.getsession); returnTextView = findViewById(R.id.returnTextView); sessionTextView = findViewById(R.id.sessionTextView);
client = new OkHttpClient.Builder() .cookieJar(cookieJar) .build();
loginButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { sendLoginRequest(); } });
getSessionButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { getSession(); } }); }
private void sendLoginRequest() { RequestBody body = new FormBody.Builder().build();
Request request = new Request.Builder() .url("https://99hu34ro6897.vicp.fun/login") .post(body) .build();
client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { runOnUiThread(() -> { returnTextView.setText("登录失败: " + e.getMessage()); Toast.makeText(MainActivity.this, "登录失败: " + e.getMessage(), Toast.LENGTH_SHORT).show(); }); }
@Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()) { runOnUiThread(() -> { returnTextView.setText("登录成功!"); Toast.makeText(MainActivity.this, "登录成功", Toast.LENGTH_SHORT).show(); }); } else { runOnUiThread(() -> { returnTextView.setText("登录失败"); Toast.makeText(MainActivity.this, "登录失败", Toast.LENGTH_SHORT).show(); }); } } }); }
private void getSession() { Request request = new Request.Builder() .url("https://99hu34ro6897.vicp.fun/getsession") .build();
client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { runOnUiThread(() -> { sessionTextView.setText("获取 session 失败: " + e.getMessage()); Toast.makeText(MainActivity.this, "获取 session 失败: " + e.getMessage(), Toast.LENGTH_SHORT).show(); }); }
@Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()) { String responseData = response.body().string(); runOnUiThread(() -> { sessionTextView.setText("Session 数据: " + responseData); }); } else { runOnUiThread(() -> { sessionTextView.setText("错误: " + response.message()); }); } } }); } }
|
这里https://www.kangdd.top/i/2024/11/26/6745c470e8c01.png在登入提交后,再次点击获取session可以得到后端发送来的数据。
4.项目截图

可以看到每次提交和获取的session都是保持一致的
5. 扩展
如果后续的页面也需要使用到这个Cookie的话,就可以把这个Cookie定义为全局静态变量,后面的页面直接引用就可以,步骤为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public class MyApplication extends Application {
private static OkHttpClient client;
@Override public void onCreate() { super.onCreate();
// 初始化 CookieJar PersistentCookieJar cookieJar = new PersistentCookieJar( new SetCookieCache(), new SharedPrefsCookiePersistor(this) );
// 初始化 OkHttpClient client = new OkHttpClient.Builder() .cookieJar(cookieJar) // 设置 CookieJar .build(); }
public static OkHttpClient getOkHttpClient() { return client; } }
|
在其他 Activity 或页面中使用相同的 OkHttpClient 实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| public class AnotherActivity extends AppCompatActivity {
private OkHttpClient client;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_another);
client = MyApplication.getOkHttpClient();
Request request = new Request.Builder() .url("http://localhost:8080/getsession") .build();
client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { runOnUiThread(() -> { Toast.makeText(AnotherActivity.this, "请求失败", Toast.LENGTH_SHORT).show(); }); }
@Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()) { String responseBody = response.body().string(); runOnUiThread(() -> { Log.d("Response", responseBody); }); } } }); } }
|