程序员

java网站页面静态化方案加工具类代码

2018-10-16  本文已影响0人  朱潘

1.概述

在大型网站中,如京东和当当商品详情界面,看到的页面基本上是静态页面。为什么都要把页面静态化呢?把页面静态化,好处有很多。例如:访问速度快,更有利于搜索引擎收录等。

一种常用的方法是通过程序将动态页面抓取并保存为静态页面,这样的页面的实际存在于服务器的硬盘中。本文采用该方法。

2.实现代码

@Service
@Lazy(false)
/**
 *  静态化页面
 *     <p>
 *         定时发送http请求,获取需要静态化的页面,另存为html文件,页面被访问时首先判断静态化页面是否生成成功。
 *         如果静态页面生成成功,则访问静态页面html。
 *         如果需要增加被静态化的页面,initUrl()方法中初始化url。
 *     </p>
 */
public class SiteStatics {

    Logger logger = Logger.getLogger(SiteStatics.class);

    /**
     * 静态化URL
     **/
    private final String STATIC_URL = System.getProperty("user.contextPath")+Global.getConfig("statics.url");

    /**
     * 静态化文件名称
     **/
    private final String STATIC_NAME = "${code}.html";

    /**
     * 静态化文件存储路劲
     **/
    private final static String STATIC_ROOT = "/statics/";

    /**
     * 静态化列表 URL - 是否静态化  1-是 0-否
     */
    public HashMap<String, Boolean> STATIC_HTML = new HashMap<String, Boolean>();

    /**
     * 判断是否是windows系统
     */
    public final static boolean IS_LOCAL = System.getProperty("os.name").startsWith("win") || System.getProperty("os.name").startsWith("Win");

    /**
     * IP
     ***/
    private final String LOGON_SITE = IS_LOCAL ? "localhost" : "localhost";

    /**
     * 端口
     ***/
    private final int LOGON_PORT = IS_LOCAL ? 80 : 80;

    /**
     * 运行锁: 程序运行时禁止访问静态化页面
     */
    public static boolean EXEC_LOCK = false;

    private HttpClient client = new HttpClient();

    //五分钟刷新一次首页静态化
    //@Scheduled(cron = "0 0/1 * * * *")
    public void run() {
        try {
            dostatic();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 初始化client
     */
    public void createClient() {
        client.getHostConfiguration().setHost(LOGON_SITE, LOGON_PORT);
    }

    /**
     * 初始化需要静态化的url
     * K: url, V: active
     * <p>
     * V: true 静态化, false 不必静态化
     * 如果需要静态化的url很多,全部放到map里面去就行了, 可以自行扩展
     * </p>
     */
    private void addUrl(String code) {
        STATIC_HTML.put(STATIC_URL.replace("${code}", code), true);
    }

    /**
     * 初始化url
     * <p>
     * 根据需求构造url,这里我就写死了,只初始化一个首页的url
     * </p>
     */
    private void initUrl() {
        String code = "wzsy";
        addUrl(code);
    }

    /**
     * 静态化
     */
    private void dostatic() throws IOException {
        EXEC_LOCK = true;
        long s = System.currentTimeMillis();
        createClient();
        STATIC_HTML = new HashMap<String, Boolean>();
        initUrl();
        File parentFolder = new File(SiteStatics.class.getResource("/").getPath()).getParentFile().getParentFile();
        File folder = new File(parentFolder.getPath() + STATIC_ROOT);
        if (!folder.exists()) {
            folder.mkdirs();
        }
        int i = 0;
        int a = STATIC_HTML.size();
        logger.info("共计缓存界面" + a + "个");
        System.out.println("共计缓存界面" + a + "个");
        for (Map.Entry<String, Boolean> entry : STATIC_HTML.entrySet()) {
            i++;
            String url = entry.getKey();
            Boolean is_static = entry.getValue();
            Integer p = (int) (Double.valueOf(i) / a * 100);
            logger.info(url + " 成功(" + p + "%)");
            System.out.println(url + " 成功(" + p + "%)");
            if (is_static) {
                GetMethod get = new GetMethod(url);
                //模拟表单元素
                File file = null;
                try {
                    String code = url.split("=")[1];
                    String fileName = STATIC_NAME.replace("${code}", code);
                    file = new File(folder + "/" + fileName);
                    int status = client.executeMethod(get);
                    if (status >= 200 && status < 400) {
                        if (!file.exists()) {
                            file.createNewFile();
                        }
                        String html = get.getResponseBodyAsString();
                        writeFile(file, html);
                        logger.info(url + " 成功(" + p + "%)");
                    } else {
                        logger.info(url + " 失败(" + p + "%)");
                    }
                } catch (Exception e) {
                    logger.error("首页缓存失败", e);
                }
                entry.setValue(false);
            }
        }

        logger.info("-----------缓存结束-----------");
        long e = System.currentTimeMillis();
        logger.info("-----------耗时:" + (e - s) / 1000 + "秒-----------");
        EXEC_LOCK = false;
    }

    /**
     * 判断静态化页面是否存在
     *
     * @param code
     * @return
     */
    public static boolean existsStatics(String code) {
        String fileName = new File(SiteStatics.class.getResource("/").getPath()).getParentFile().getParentFile().getPath() + STATIC_ROOT + "/" + code + ".html";
        File file = new File(fileName);
        if (file.exists() && !EXEC_LOCK) {
            return true;
        }
        return false;
    }

    public static void main(String[] args) {
        System.out.println(SiteStatics.class.getResource("/").getPath());
    }

    /**
     * 将配置字符串写出到文件
     *
     * @param file 文件路径
     * @param str  待写入的字符串
     */
    private void writeFile(File file, String str) {
        try {
            if (!file.exists()) {
                file.createNewFile();
            }
            OutputStreamWriter write = new OutputStreamWriter(new FileOutputStream(file), "UTF-8");
            BufferedWriter writer = new BufferedWriter(write);
            writer.write(str);
            writer.close();
        } catch (Exception e) {
            System.out.println("写文件内容操作出错");
            e.printStackTrace();
        }

    }
}

3.访问控制

        String code = httpServletRequest.getParameter("code");
        if(SiteStatics.existsStatics(code)){
            String static_name = Global.getConfig("statics.url").replace("${code}", code);
            return "redirect:"+static_name;
        }

欢迎关注我的公众号“java工会”,与君共勉

上一篇下一篇

猜你喜欢

热点阅读