Retrofit界面如何添加cookies来存储数据

Retrofit interface how to add cookies to store data

我有一个 android studio 应用程序,它通过用户身份验证连接到 nodejs 后端服务器。我可以从我的应用程序登录和注册,但它不存储会话。所以我还不能获得基于会话的功能。

我需要添加功能来存储会话。为此,我如何使用改造界面来做到这一点。 我想登录启动一个会话,这样我就可以让用户登录访问服务器上的其他路由。

或者 android 工作室是否有另一个允许 cookie 和会话的界面? 改造界面


public interface RetrofitInterface {

            
    @POST("/login")
    Call<Login_result> executeLogin(@Body HashMap<String, String> map);
            
    @POST("/signup")
    Call<Void> executeSignup(@Body HashMap<String, String>map);
            
    @POST("/add_data")
    Call<Void> executeAdd_data(@Body HashMap<String, String>map);
            
    @POST("/logout")
    Call<Void> executeLogout(@Body HashMap<String, String>map);
            
    @GET("/test")
    Call<Void> executeTest();

}
**Main code**

```java


/*Updated this*/
    Context context = this;

        retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .client(new OkhttpClient.builder()
                        .addInterceptor(new ReceivedCookiesInterceptor(context)
                                .addInterceptor(new AddCookiesInterceptor(context)
                                ).build())
                        .addConverterFactory(GsonConverterFactory.create())
                        .build();
        retrofitInterface = retrofit.create(RetrofitInterface.class);

登录码


    HashMap<String,String> map = new HashMap<>();
                //map.put("email",emailEdit.getText().toString());//
                map.put("username", usernameEdit.getText().toString());
                map.put("password", passwordEdit.getText().toString());

                Call<Login_result> call = 
                retrofitInterface.executeLogin(map);//Run the post
                call.enqueue(new Callback<Login_result>()
                {

                    @Override
                    public void onResponse(Call<Login_result> call, Response<Login_result> response) {
                        if(response.code() == 200)
                        {
                            /*Login_result result = response.body();
                            AlertDialog.Builder builder1 = new AlertDialog.Builder(MainActivity.this);
                            builder1.setTitle(result.getUsernname());
                            builder1.setMessage(result.getEmail());

                            builder1.show();*/
                            Toast.makeText(MainActivity.this, "Logged in", Toast.LENGTH_SHORT).show();


                        }else if(response.code() == 404)
                        {
                            Toast.makeText(MainActivity.this, "Incorrect usernanme or password", Toast.LENGTH_SHORT).show();
                        }
                    }

                    @Override
                    public void onFailure(Call<Login_result> call, Throwable t) {
                        Toast.makeText(MainActivity.this, t.getMessage(),Toast.LENGTH_LONG).show();
                    }
                });

您需要创建两个 interceptors 并将 cookie 信息存储在共享首选项中

public class ReceivedCookiesInterceptor implements Interceptor {

    private Context context;
    public ReceivedCookiesInterceptor(Context context) {
        this.context = context;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        Response originalResponse = chain.proceed(chain.request());

        if (!originalResponse.headers("Set-Cookie").isEmpty()) {
            HashSet<String> cookies = (HashSet<String>) PreferenceManager.getDefaultSharedPreferences(context).getStringSet("PREF_COOKIES", new HashSet<String>());

            for (String header : originalResponse.headers("Set-Cookie")) {
                cookies.add(header);
            }

            SharedPreferences.Editor memes = PreferenceManager.getDefaultSharedPreferences(context).edit();
            memes.putStringSet("PREF_COOKIES", cookies).apply();
            memes.commit();
        }

        return originalResponse;
    }
}

然后反向将 cookie 添加到传出请求

public class AddCookiesInterceptor implements Interceptor {

    public static final String PREF_COOKIES = "PREF_COOKIES";
    private Context context;

    public AddCookiesInterceptor(Context context) {
        this.context = context;
    }

    @Override
    public Response intercept(Interceptor.Chain chain) throws IOException {
        Request.Builder builder = chain.request().newBuilder();

        HashSet<String> preferences = (HashSet<String>) PreferenceManager.getDefaultSharedPreferences(context).getStringSet(PREF_COOKIES, new HashSet<String>());

        Request original = chain.request();
        if(original.url().toString().contains("distributor")){
            for (String cookie : preferences) {
                builder.addHeader("Cookie", cookie);
            }
        }

        return chain.proceed(builder.build());
    }
}

然后您需要将 Retrofit 实例更改为以下内容

        retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .client(new OkhttpClient.builder()
                        .addInterceptor(new ReceivedCookiesInterceptor(context)
                        .addInterceptor(new AddCookiesInterceptor(context) 
                ).build())
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        retrofitInterface = retrofit.create(RetrofitInterface.class);