我现在在加载验证码cookie 需要在retrofit先请求一遍才能记录cookie 但是验证码那块的获取的是image 我解析json格式时会报错
因为图灵的图是直接图片 我拿去解析object了 错误如下
Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1 path $
现在有几个问题需要请教一下
1.图灵图片需要怎样请求retrofit object-->解析错误 《 虽然Glide直接可以显示出来 但是没办法在这里拿到它的cookie
2.拦截器加cookie后 login登录的时候 携带cookie后 这样直接请求可以吗
3.cookie还有更简洁的获取方式吗 在Glide请求的时候也可以拿到 就可以先忽略1。了
我贴一贴请求的东西哈 可能格式不太美观
请求类
public interface GetSugarApi {
@GET("uc/ut/captcha")
Observable<String> getImage(@Query("code") String code);
@GET("uc/user/avatar/{phone}")
Observable<Sugar_photoBean> getPhoto(@Path("phone") String phone);
@POST("uc/user/login/{captcha}")
@FormUrlEncoded // 表单请求--> 不支持
Observable<Sugar_LoginBean> login(@Header("Content-Type") String s, @Path("captcha") String captcha, @Field("phoneNum") String phoneNum, @Field("password") String password);
@POST("uc/user/login/{captcha}")
Observable<Sugar_LoginBean> login2(@Path("captcha")String captcha, @Body RequestBody body);
}
实现类
public class LoginActivity extends BaseActivity {
private ImageView img_code;
private EditText et_code;
private Button btn_login;
int i = 0;
@Override
public void initView() {
btn_login = findViewById(R.id.btn_login);
et_code = findViewById(R.id.et_code);
img_code = findViewById(R.id.img_code);
}
private void login(String code) {
LoginBean loginBean = new LoginBean("136XXXX3056","XXXXmd5");
RequestBody body = FormBody.create(MediaType.parse("application/json; charset=utf-8"), new Gson().toJson(loginBean));
Observable loginObservable = sugarApi.login2(code,body);
loginObservable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Sugar_LoginBean>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e("-->","loginObservable onSubscribe");
}
@Override
public void onNext(@NonNull Sugar_LoginBean loginBean) {
Log.e("-->","loginObservable onSubscribe = "+loginBean.toString()); // 在这里总是验证码错误 大牛们说没携带cookie 后面在网上找了一种拦截器讲 cookie缓存的 贴在下面哈
}
@Override
public void onError(@NonNull Throwable e) {
Log.e("-->","login onError "+ e.getMessage().trim());
}
@Override
public void onComplete() {
}
});
}
@Override
public int getLayoutId() {
return R.layout.activity_login;
}
private Retrofit retrofit;
private OkHttpClient okHttpClient ;
private GetSugarApi sugarApi;
private String baseUri = "https://api.sunofbeach.net/";
@Override
public void initData() {
okHttpClient = new OkHttpClient.Builder()
.addInterceptor(new AddCookiesInterceptor(this))
.addInterceptor(new SaveCookiesInterceptor(this)).build();
retrofit = new Retrofit.Builder()
.baseUrl(baseUri)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(okHttpClient)
.build();
sugarApi = retrofit.create(GetSugarApi.class);
requestTranslation();
loadImg();
img_code.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
i = i++;
Glide.with(LoginActivity.this).load("https://api.sunofbeach.net/uc/ut/captcha?code="+i).into(img_code);
}
});
btn_login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String code = et_code.getText().toString();
login(code);
}
});
}
private void loadImg() {
int max = 9999 , min = 1000;
int ranNum = (int) ( Math.random() * ( max - min ) + min );
Log.e("-->","random ranNum = "+ ranNum );
Glide.with(this).load(baseUri+"uc/ut/captcha?code="+ranNum).into(img_code);
Observable<String> observable = sugarApi.getImage(ranNum+"");
// // 创建的时候请求
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onNext(@NonNull String s) {
Log.e("-->","loadImg onNext "+s.toString());
}
@Override
public void onError(@NonNull Throwable e) {
Log.e("-->","loadImg onError "+e.getMessage().toString());
}
@Override
public void onComplete() {
}
});
}
两个cookie拦截器类
public class SaveCookiesInterceptor implements Interceptor {
private static final String COOKIE_PREF = "cookies_prefs";
private Context mContext;
public SaveCookiesInterceptor(Context context) {
mContext = context;
}
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
//set-cookie可能为多个
if (!response.headers("set-cookie").isEmpty()) {
List<String> cookies = response.headers("set-cookie");
String cookie = encodeCookie(cookies); //解析
saveCookie(request.url().toString(), request.url().host(), cookie); // 存入
}
return response;
}
//整合cookie为唯一字符串
private String encodeCookie(List<String> cookies) {
StringBuilder sb = new StringBuilder();
Set<String> set=new HashSet<>();
for (String cookie : cookies) {
String[] arr = cookie.split(";");
for (String s : arr) {
if(set.contains(s))continue;
set.add(s);
}
}
Iterator<String> ite = set.iterator();
while (ite.hasNext()) {
String cookie = ite.next();
sb.append(cookie).append(";");
}
int last = sb.lastIndexOf(";");
if (sb.length() - 1 == last) {
sb.deleteCharAt(last);
}
return sb.toString();
}
//保存cookie到本地,这里我们分别为该url和host设置相同的cookie,其中host可选
//这样能使得该cookie的应用范围更广
private void saveCookie(String url,String domain,String cookies) {
SharedPreferences sp = mContext.getSharedPreferences(COOKIE_PREF, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
if (TextUtils.isEmpty(url)) {
throw new NullPointerException("url is null.");
}else{
editor.putString(url, cookies);
}
if (!TextUtils.isEmpty(domain)) {
editor.putString(domain, cookies);
}
editor.apply();
}
}
public class AddCookiesInterceptor implements Interceptor {
private static final String COOKIE_PREF = "cookies_prefs";
private Context mContext;
public AddCookiesInterceptor(Context context) {
mContext = context;
}
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request.Builder builder = request.newBuilder();
String cookie = getCookie(request.url().toString(), request.url().host());
if (!TextUtils.isEmpty(cookie)) {
builder.addHeader("Cookie", cookie);
}
return chain.proceed(builder.build());
}
private String getCookie(String url, String domain) {
SharedPreferences sp = mContext.getSharedPreferences(COOKIE_PREF, Context.MODE_PRIVATE);
if (!TextUtils.isEmpty(url)&&sp.contains(url)&&!TextUtils.isEmpty(sp.getString(url,""))) {
return sp.getString(url, "");
}
if (!TextUtils.isEmpty(domain)&&sp.contains(domain) && !TextUtils.isEmpty(sp.getString(domain, ""))) {
return sp.getString(domain, "");
}
return null;
}
}
兄弟,别急,我现在就搞一个登录的demo出来,只要用我的demo就可以实现登录,和以后所有需要登录的操作。给我一首歌的时间。
我用okhttp单独请求了 图灵链接 cookie 应该有了 请求也携带同样的cookie 但也还是失败 在手机获取的code总是同一个 我现在把“https://api.sunofbeach.net/uc/ut/captcha?code=123122” 写死了 不太懂