玩Android开发10-----文章收藏功能(Postman的使用 + Cookie机制 + OkHttp拦截器拦截Cookie)

在进行收藏操作时,一般都会使用post方式将收藏信息提交到后台服务器,那么在网站中,是不能用输入网址的形式获取数据的,所以提供了一个工具Postman《Postman下载地址》

Postman的使用很简单,输入要请求的网址,加上要请求的参数,它会自动拼接成一条post请求。
在这里插入图片描述
然后发送请求,就会得到服务器的响应。
在这里插入图片描述
所以在收藏时,如果想知道服务器返回的数据是什么样的,就可以使用Postman。

1、收藏

其实收藏很简单,只需要根据文章的id,来将收藏请求post到服务器,服务器会将信息保存,用户可以查看保存信息。

我在此设计的是,长按文章Item,就会收藏该文章。

 //长按收藏
        lv_main.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                int item = position - headCount;
                int aid = list.get(item).getId();
                //收藏
                fPresenter.getCollection(aid);
                return false;
            }
        });

在解析服务器返回的数据时,会做一系列的判断

@Override
    public void showCollection(CollectBean collectBean) {
        Log.e("TAG","coll==="+collectBean);
        if(collectBean.getErrorCode() == 0 && collectBean.getErrorMsg().equals("")){
            Toast.makeText(getContext(),"收藏成功",Toast.LENGTH_SHORT).show();
        }else{
            Toast.makeText(getContext(),collectBean.getErrorMsg(),Toast.LENGTH_SHORT).show();
        }
    }

在测试的时候,并没有收藏成功,而是出现了错误信息。

data=null, errorCode=-1001, errorMsg='请先登录!'

之前明明已经登录了,为什么还是要我登录?原来只是你自己根据信息解析出来的数据,判断服务器返回的信息是否符合要求,而自行进入到了主界面,但是系统和服务器并没有认为你已经登录了,如下代码(登录代码):

 if(loginBean.getErrorCode() == 0 && loginBean.getErrorMsg().equals("")){
            //登录成功
            Intent intent = new Intent();
            intent.putExtra("username",username);
            intent.setClass(LoginActivity.this,MainActivity.class);
            startActivity(intent);
            //保存登录信息
            SPUtils.getInstance().saveInfo("login",true);
            finish();
        }else{
            Toast.makeText(this,loginBean.getErrorMsg(),Toast.LENGTH_SHORT).show();
        }

要如何解决这个问题,那么就引进了Cookie。

2、Cookie

Cookie可以理解为一段保存在客户端的字符串,就拿登录这个例子来说,我们第一次登录的时候,会通过用户名和密码来登录,去向服务器发起请求,这个时候,服务器接收到了登录请求之后,会判断用户是否符合注册信息,如果符合注册信息,那么就会将登录成功的信息 + Cookie一起发送到客户端,客户端需要将Cookie持久保存在客户端,等到下一次请求时,我们不需要使用用户名和密码登录,只需要使用Cookie,去验证服务器,这也有效地避免了用户信息被第三方劫持;Cookie可以搭配时间戳,来保证它的有效期,当有效期失效后,会重新使用用户名和密码登录,获取新的Cookie,这也有效地避免了第三方劫持Cookie,持续攻击服务器;而且这样也有效地解决了Http无状态的特性

常见的场景:比如说我们玩一个APP,登录之后,不需要再重复登录,但是很长时间没玩,你再次打开这个APP的时候,它会提示你再次登录,就是因为Cookie已经失效了,你需要重新获取新的Cookie。

当用户登录时,服务器端返回的Cookie
在这里插入图片描述
在这里插入图片描述
所以,如果服务器想要客户端保存Cookie到本地,那么在响应头中,就添加了一个Set-Cookie字段,从上图中,能够看到这个信息。

那么如何获取这个Cookie字段,就是通过OkHttp拦截器完成,因为Retrofit的底层也是OkHttp。

(1)拦截Cookie

在用户登录时,需要将服务器返回的cookie信息保存到本地,所以需要通过OkHttp拦截器,将“Set-Cookie”的字段值保存在本地

/**
 * 在登录时获取
 */
public class CookieIntercepter implements Interceptor {
    public CookieIntercepter() {
        super();
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        //执行请求获取服务器返回的响应
        Response response = chain.proceed(chain.request());
        if(!response.headers("Set-Cookie").isEmpty()){
            //解析Cookie
            for (String header : response.headers("Set-Cookie")) {
                if(header.contains("JSESSIONID")){
                    String cookie = header.substring(header.indexOf("JSESSIONID"), header.indexOf(";"));
                    SPUtils.getInstance().saveInfo("cookie",cookie);
                }
            }
        }
        return response;
    }
}

这样在本地就保存了服务器返回的cookie。
在这里插入图片描述
这里的JSESSIONID是对应服务器中的session的位置,所以在向服务器请求收藏时,要将这个cookie信息添加到请求头里,然后服务器接收到这个请求之后,会找到这个客户端对应的session,也就是说每个用户对应一个session,你在第一次登录的时候,服务器给你一个cookie,你保存在本地(客户端),对应的服务器也生成一个session保存客户端信息。

(2)添加头信息到请求

/**
 * 将Cookie添加到请求的头部(在收藏时使用)
 */
public class AddCookieToHeader implements Interceptor {
    public AddCookieToHeader() {
        super();
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request.Builder request = chain.request().newBuilder();
        String cookie = SPUtils.getInstance().getInfo("cookie", null);
        if(cookie != null) {
                request.addHeader("Cookie", cookie);
            }
        return chain.proceed(request.build());
        }
}

然后可以设置OkHttp的拦截,设置到Retrofit的cilent中;

OkHttpClient client = new OkHttpClient.Builder()
            .addInterceptor(new CookieIntercepter())
            .build();

    OkHttpClient cookieClient = new OkHttpClient.Builder()
            .addInterceptor(new AddCookieToHeader())
            .build();
 Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(Constant.BASE_URL)
                .client(client)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

这个时候去服务端请求,就知道是哪个客户端来请求收藏信息,就不会再提示登录了。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Awesome_lay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值