OkHttp保存session

本文探讨了SpringBoot应用中如何使用Google Kaptcha生成验证码并利用HttpSession与Cookie保存数据,确保在Android端通过Okhttp获取验证码时保持一致性。重点在于理解会话管理在验证码流程中的作用。
摘要由CSDN通过智能技术生成
  1.  如果不保存session的话,在每次通过http访问服务器,服务器都会新开一个线程,线程中不保存前一次访问留下的session记录。
  2. 而对于获取验证码等操作,这些都需要上一次访问服务器记录的session,如不保存session的话那么在服务器端对应的验证码则为空。
  3. 2022-10-23 18:03:09.377 DEBUG 640 --- [nio-8080-exec-3] com.tian.sms.util.CodeCheck              : das
    2022-10-23 18:03:09.377 DEBUG 640 --- [nio-8080-exec-3] com.tian.sms.util.CodeCheck              : null

  • 服务器采用SpringBoot服务器,验证码生成采用Google的kaptcha框架。
package com.tian.sms.controller;

import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.imageio.ImageIO;
import javax.naming.ldap.PagedResultsControl;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.IOException;

//获取验证码接口
@Controller
public class KaptchaController {
    private static final Logger log = LoggerFactory.getLogger(KaptchaController.class);

    public static String CHECK_CODE;
    @Autowired
    private Producer kaptchaProducer;

    @RequestMapping("/kaptcha")
    public void getKaptchaImage(HttpServletRequest request, HttpServletResponse response) throws IOException {
        HttpSession session = request.getSession();
        response.setDateHeader("Expires", 0);
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
        response.setHeader("Pragma", "no-cache");
        response.setContentType("image/jpeg");
        //生成验证码
        String capText = kaptchaProducer.createText();
        log.debug(capText);
        CHECK_CODE = capText;
        session.setAttribute(Constants.KAPTCHA_SESSION_KEY, capText);
        log.debug(session.getAttribute(Constants.KAPTCHA_SESSION_KEY).toString());
        log.debug("kaptcha"+request.getParameter("date"));
        //向客户端写出
        BufferedImage bi = kaptchaProducer.createImage(capText);
        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(bi, "jpg", out);
        try {
            out.flush();
        } finally {
            out.close();
        }
    }

    public String getCheckCode(){
        return CHECK_CODE;
    }

}
  • 由上可看出,验证码的数据是保存在服务器的session中的,所以Android端不能是同Glide框架来直接获取图片,暂时未知Glide框架如何保存session,所以采用Okhttp框架来发送请求获取session,并将session保存。
package com.tian.mygraduatesign.activity;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Parcel;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.bumptech.glide.Glide;
import com.tian.mygraduatesign.R;
import com.tian.mygraduatesign.pojo.School;
import com.tian.mygraduatesign.pojo.User;
import com.tian.mygraduatesign.util.GetJson;
import com.tian.mygraduatesign.util.UrlUtil;

import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import kotlin.reflect.KVariance;
import okhttp3.Call;
import okhttp3.FormBody;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okio.BufferedSink;

public class LoginActivity extends Activity {
    ImageView codeCheck;
    LoginActivity loginActivity;
    Date date;
    Spinner spinnerSchool;
    TextView accountText;
    TextView passwordText;
    TextView codeText;
    OkHttpClient okHttpClient;
    List<String> schoolName;
    List<String> schoolEName;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.login_layout);
        codeCheck = findViewById(R.id.login_check_img);
        loginActivity = this;
        date = new Date();
        spinnerSchool = findViewById(R.id.login_spinner);
        accountText = findViewById(R.id.login_account);
        passwordText = findViewById(R.id.login_password);
        codeText = findViewById(R.id.login_check_code);
        okHttpClient = new OkHttpClient();
imgChange.start();
        Glide.with(this).load(UrlUtil.url + "/kaptcha?date=" + date.getTime()).into(codeCheck);
        codeCheck.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //刷新验证码图片 验证码具有网络缓存 需要添加时间戳参数
                date = new Date();
                imgChange.start();
            }
        });

    }

    Thread imgChange = new Thread(new Runnable() {
        @Override
        public void run() {
            Request request = new Request.Builder().addHeader("cookie", GetJson.session).url(UrlUtil.url + "/kaptcha?date=" + date.getTime()).get().build();
            Call call = okHttpClient.newCall(request);
            try {
                Response response = call.execute();
                //修改session
                Headers headers = response.headers();
                List<String> cookies = headers.values("Set-Cookie");
                String s = cookies.get(0);
                GetJson.session = s.substring(0,s.indexOf(";"));
                //发送图片byte数组给handler处理
                byte[] bytes = response.body().bytes();
                Message imgMsg = new Message();
                Bundle bundle = new Bundle();
                bundle.putByteArray("values",bytes);
                imgMsg.setData(bundle);
                codeImgHandler.sendMessage(imgMsg);
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    });
 //处理验证码图片UI更改
    Handler codeImgHandler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            Bundle data = msg.getData();
            byte[] values = data.getByteArray("values");
            Bitmap bitmap = BitmapFactory.decodeByteArray(values,0,values.length);
            codeCheck.setImageBitmap(bitmap);
        }
    };

    public void loginUser(View view) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                Message loginMsg = new Message();
                Bundle bundle = new Bundle();
                //获取spinner控件的选择的学校简写
                int i = schoolName.indexOf(((TextView)spinnerSchool.getSelectedView()).getText().toString());
                FormBody formBody = new FormBody.Builder().add("school",schoolEName.get(i)).add("account",accountText.getText().toString())
                        .add("password",passwordText.getText().toString())
                        .add("code",codeText.getText().toString()).build();

                //发送表单请求
                Request build = new Request.Builder().addHeader("cookie",GetJson.session).url(UrlUtil.url + "/login").post(formBody).build();
                Call call = okHttpClient.newCall(build);
                try {
                    Response execute = call.execute();
                    //修改session
                    Headers headers = execute.headers();
                    List<String> cookies = headers.values("Set-Cookie");
                    String s = cookies.get(0);
                    GetJson.session = s.substring(0,s.indexOf(";"));
                    //获取json字符串
                    String body = execute.body().string();
                    bundle.putString("values",body);
                    loginMsg.setData(bundle);
                    loginHandle.sendMessage(loginMsg);
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }).start();
    }
}
  • 这样就能将session通过cookie进行保存。
     
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Devotes

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

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

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

打赏作者

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

抵扣说明:

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

余额充值