Java EE后台模拟浏览器有状态请求页面

为解决Struts2页面初次加载慢的问题,通过在Tomcat启动后预先访问页面进行优化。采用创建线程的方式判断Tomcat启动完成,并通过模拟登录绕过验证,确保请求在同一Session中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

近期,发现Struts2的页面初次加载时很慢,想了个点子,在tomcat启动完后预先访问这些页面。主要出现两个问题:

1:什么时候检测到tomcat启动完成?

2:页面访问都是需要预先登录的,而且还有验证码,如何绕过去?

对于第一个问题,直观的想法是在最后一个Listener中做,但是如果直接在Listener中做会导致死锁,因为Listener不返回Tomcat是不会接受请求的。一个办法是创建一个线程,在线程中请求页面,这样这个线程会自动阻塞到Tomcat启动完毕。

第二个问题,比较麻烦。思路是先模拟登录,然后再请求页面。需要特别注意JSESSIONID的处理,确保每次请求都在一个Session中。请求部分的代码如下:

protected static String postUrl(String strUrl, String strParams, String []strSession, String strMethod) throws IOException {
        URL url = new URL(strUrl);
        HttpURLConnection connection = (HttpURLConnection)url.openConnection();
        
        if(strSession!=null && strSession.length>0 && !Utility.isEmpty(strSession[0])) {
            connection.setRequestProperty( "Cookie", strSession[0]);
        }
        
        connection.setRequestMethod(strMethod);
        connection.setRequestProperty("User-Agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows 2000)");                    
          
          if(!Utility.isEmpty(strParams)) {
              connection.setDoOutput(true);
            OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream(), "GB2312");
            out.write(strParams);
            out.flush();
            out.close();
          }
        
        String sCurrentLine = "";
        String sTotalString = "";
        InputStream l_urlStream = connection.getInputStream();
        BufferedReader l_reader = new BufferedReader(new InputStreamReader(l_urlStream));
        
        while ((sCurrentLine = l_reader.readLine()) != null) {
            sTotalString += sCurrentLine + "\r\n";
        }

        if(strSession!=null && strSession.length>0) {
            String session_value = connection.getHeaderField("Set-Cookie" );
            
            if(!Utility.isEmpty(session_value) && Utility.isEmpty(strSession[0])) {
                String[] sessionId = session_value.split(";");
                strSession[0] = sessionId[0];
            }
        }
        
        return sTotalString;
    }

思路比较清晰,一开始不设置SessionId,如果Tomcat创建了SessionId,则以后都用这个SessionId。获取了SessionId后,Tomcat返回其他SessionId时一定忽略,这点特别要注意。登录的代码如下:

protected static void login(String []strSession) {
        try {
            String strUrl = ApplicationParameter.URLPREFIX + "/codeimage?86";
            postUrl(strUrl, "", strSession, "GET");
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        try {
            String strUrl = ApplicationParameter.URLPREFIX + "/j_spring_security_check?logurl=/index.action&Verify=false&logintype=wz";
            JdbcTemplate jdbcTemplate = (JdbcTemplate)SpringTools.getBean("jdbcTemplate");
            List<Map<String, String>> lstTmp = jdbcTemplate.queryForList("select t.pwd as pwd from t_user t where t.name = ?", new Object[]{FETCHEARLY_USERNAME});
            String strPassWd = lstTmp!=null&&lstTmp.size()>0 ? lstTmp.get(0).get("PWD") : "";
            String strSessionId = strSession[0].substring(strSession[0].indexOf("=")+1);
            strSessionId = strSessionId.indexOf(";")==-1 ? strSessionId : strSessionId.substring(0, strSessionId.indexOf(";"));
            String strParams = "j_username=" + FETCHEARLY_USERNAME
                    + "&j_password=" + (strPassWd.length()>=4 ? strPassWd.substring(0, strPassWd.length()-4) : "")
                    + "&imageCodeName=" + SessionListener.getSession(strSessionId).getAttribute("KAPTCHA_SESSION_KEY");
            postUrl(strUrl, strParams, strSession, "POST");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

思路也很明确,先请求验证码页面,目的是让Tomcat为我们生成一个验证码,然后我们就可以在Session中获取验证码了。账户和密码是直接从数据库中获取的。登录框架是Spring Security。主要的代码如下:

protected static void logoff(String []strSession) {
        String strUrl = ApplicationParameter.URLPREFIX + "/j_spring_security_logout";
        String strParams = "";
        
        try {
            postUrl(strUrl, strParams, strSession);
        } catch (IOException e) {
        }
    }

原理也很简单,直接访问Spring Security的注销页面即可。

登录后就可以进行有状态的页面访问了,只要确保SessionId一致即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值