1. A Cookie is introduced
Personally, I understand that cookies are actually to record some information and status behaviors of users. In such a scenario, after the user logs in successfully, the server will return a Cookie, which contains the user’s login status information, etc., so that when the user accesses his favorite list, add this Cookie, then he can directly obtain the article list. If there is no Cookie, How does the server know which user’s article list you’re trying to get?
On the browser, the returned Cookie will be saved in the browser, and the Cookie will be automatically added in the next visit. On the Android side, we need to save the Cookie returned by the server and add it in the next visit. As for how to save (Cookie persistence), there are many methods, you can use database, file, SharedPreferences, you can also use the CookieManager of Webview.
You can read this article about cookies and the summary of their use in Android in great detail. Just read this article
We have already described how to add headers in the previous article, but obviously we can’t do this. We can’t write headers on every API that needs cookies or add them dynamically. That would be too tedious, so we will add them dynamically through interceptors.
2. Interface description
For this article, I will use the login interface and the favorite article list interface of the Wandroid website
landing
https://www.wanandroid.com/user/loginMethod: POST Parameters: username, passwordCopy the code
After login, the system returns the account password in the cookie. After persistent cookie storage is configured on the client, the login is automatically authenticated.
List of favorite articles
https://www.wanandroid.com/lg/collect/list/0/jsonMethod: GET Parameter: page number: concatenated in the link from0Start.Copy the code
After login on the website, can direct access to the www.wanandroid.com/lg/collect/… Check out your favorite articles.
You can check it out atWeb siteRegister an account and bookmark a few articles for use below.
3. Relationship between Retrofit and OkHttp
Why OkHttp? Because Retrofit is basically implemented using OkHttp, it’s just wrapped around it. We can set the request header by Interceptor from OkHttp, The request headers are then modified via retrofit.client(okHttpClient), which saves us from adding them manually.
4. Interceptor creation
Here we create two interceptors, one for receiving cookies on login and saving them locally, and one for adding cookies to requests on access.
4.1 Interception Cookies are saved to the local interceptor
4.1.1 Creating an Interceptor inherits from Interceptor
public class ReceivedCookiesInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
// Intercepted cookies are stored in originalResponse
Response originalResponse = chain.proceed(chain.request());
// Prints cookie information
Log.i(TAG, "intercept: "+ originalResponse.headers("Set-Cookie").toString()); .returnoriginalResponse; }}Copy the code
The response obtained by chain.proceed(chain.request()) saves the intercepted cookie information.
Log. I (TAG, “Intercept: “+ OriginalResponse.headers (” set-cookie “).tostring ()); Prints header logs
We can see the cookie information returned by the network request. All we need to do is save this cookie locally.
4.1.2 Saving Cookie Information locally
I’m going to store cookies in a sharepreference
-
Check that the header of set-cookie is not empty
if(! originalResponse.headers("Set-Cookie").isEmpty()) { ... } Copy the code
-
The Cookie information is looped into the HashSet collection
HashSet<String> cookies = new HashSet<>(); for(String header: originalResponse.headers("Set-Cookie")) { cookies.add(header); } Copy the code
-
Cookie information is saved locally through SharePreference
// Save the sharePreference file named cookieData SharedPreferences sharedPreferences = context.getSharedPreferences("cookieData", Context.MODE_PRIVATE); SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putStringSet("cookie", cookies); editor.commit(); Copy the code
4.1.3 Complete code
public class ReceivedCookiesInterceptor implements Interceptor {
public ReceivedCookiesInterceptor(a) {
super(a); }@Override
public Response intercept(Chain chain) throws IOException {
Response originalResponse = chain.proceed(chain.request());
// Get the cookie returned by the request
if(! originalResponse.headers("Set-Cookie").isEmpty()) {
HashSet<String> cookies = new HashSet<>();
for(String header: originalResponse.headers("Set-Cookie"))
{
LogUtil.i(TAG, "The intercepted cookie is:"+header);
cookies.add(header);
}
// Save the sharePreference file named cookieData
SharedPreferences sharedPreferences = App.getInstance().getSharedPreferences("cookieData", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putStringSet("cookie", cookies);
editor.commit();
}
returnoriginalResponse; }}Copy the code
4.2 Adding an Interceptor for Local Cookies for Network Access
4.2.1 Creating an Interceptor inherits from Interceptor
public class AddCookiesInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {... }}Copy the code
4.2.2 Read cookies from Sharepreference and add them to the header
Request.Builder builder = chain.request().newBuilder();
HashSet<String> perferences = (HashSet) App.getInstance().getSharedPreferences("cookieData", Context.MODE_PRIVATE).getStringSet("cookie".null);
if(perferences ! =null) {
for (String cookie : perferences) {
builder.addHeader("Cookie", cookie); }}return chain.proceed(builder.build());
Copy the code
4.2.3 Complete code
public class AddCookiesInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request.Builder builder = chain.request().newBuilder();
HashSet<String> perferences = (HashSet) App.getInstance().getSharedPreferences("cookieData", Context.MODE_PRIVATE).getStringSet("cookie".null);
if(perferences ! =null) {
for (String cookie : perferences) {
builder.addHeader("Cookie", cookie); }}returnchain.proceed(builder.build()); }}Copy the code
5. Application
5.1 Login Cookie Interception
5.1.1 Creating an OkhttpClient object
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new ReceivedCookiesInterceptor())
.build();
Copy the code
5.1.2 Create a Retrofit object and add this OkhttpClient object
private Retrofit retrofitLogin;
retrofitLogin = new Retrofit.Builder()
.baseUrl("https://a/")
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
Copy the code
5.1.3 Creating Interface Objects for Access
public interface Api {
// Login interface
@FormUrlEncoded
@POST
Call<UserBean> login(@Url String url, @FieldMap Map<String, String> param);
}
Copy the code
private Api loginApi;
loginApi = retrofitLogin.create(Api.class);
Copy the code
Map<String, String> param = new HashMap<>();
param.put("username", etUsername.getText().toString());
param.put("password", etPwd.getText().toString());
loginApi.login(loginUrl, param).enqueue(new Callback<UserBean>() {
@Override
public void onResponse(Call<UserBean> call, Response<UserBean> response) {
if(response ! =null&& response.body() ! =null) {
if (response.body().getErrorCode() == 0) {
Toast.makeText(getApplicationContext(), "Login successful", Toast.LENGTH_SHORT).show(); }else {
Toast.makeText(getApplicationContext(), "Login failed"+ response.body().getErrorCode() + response.body().getErrorMsg(), Toast.LENGTH_SHORT).show(); }}}@Override
public void onFailure(Call<UserBean> call, Throwable t) {
Toast.makeText(getApplicationContext(), "Login failed"+t, Toast.LENGTH_SHORT).show(); }}); }else {
Toast.makeText(this."Please enter complete user information", Toast.LENGTH_SHORT).show();
}
Copy the code
5.2 Get favorites list attached local Cookie
5.2.1 Creating an OkhttpClient object
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(new AddCookiesInterceptor())
.build();
Copy the code
5.2.2 Create a Retrofit object and add this OkhttpClient object
retrofitCollect = new Retrofit.Builder()
.baseUrl("https://www.wanandroid.com/")
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build();
Copy the code
5.2.3 Creating Interface Objects for Access
public interface Api {
// Get the list of favorites
@GET("lg/collect/list/{page}/json")
Call<MyCollectionBean> getCollecEssay(@Path("page") int page);
}
Copy the code
private Retrofit retrofitCollect;
private Api getCollectApi;
getCollectApi = retrofitCollect.create(Api.class);
Copy the code
getCollectApi.getCollecEssay(0).enqueue(new Callback<MyCollectionBean>() {
@Override
public void onResponse(Call<MyCollectionBean> call, Response<MyCollectionBean> response) {
if(response ! =null&& response.body() ! =null) {
if (response.body().getErrorCode() == 0) {
Log.i(TAG, "OnResponse: Succeeded in getting the list of articles");
for (int i = 0; i < response.body().getData().getDatas().size(); i++) {
Log.i(TAG, "\n Collection title:"+ response.body().getData().getDatas().get(i).getTitle()); }}else {
Log.i(TAG, "OnResponse: Failed to get list of articles"+response.body().getErrorMsg()); }}}@Override
public void onFailure(Call<MyCollectionBean> call, Throwable t) {
Log.i(TAG, "OnResponse: Failed to get list of articles"+t); }});Copy the code
6. Summary
That’s all. See Github for the code.
In fact, the purpose of using the interceptor is to save the Cookie information locally and add cookies to the header information through the interceptor. It is to simplify the step of adding the header information manually.
The above is all the content, if there is a mistake in the place also hope to point out, to help you if you trouble to see the officer to like a start. The article about Retrofit image uploading is still being edited. As for how to use cloud server to write an image uploading interface for everyone, I’m still trying to figure out how to do it.
7. Refer to the article
Retrofit uses OkHttp to save and add cookies
Android cookies are received and sent
Cookie introduction and the use of Android summary in detail, just read this article