HttpClient+定时实现页面静态化

在这里插入图片描述
页面静态化,就是将原本用户访问的url后的最终结果转换为静态页面 (可以是html) ,那么用户在以后的访问直接访问静态页面即可,这样就可以避免中间访问网络或是数据库的过程,从而降低了服务器压力。
github地址

文件路径
在这里插入图片描述
引入依赖

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.6</version>
        </dependency>
    </dependencies>

application.yml

spring:
  thymeleaf:
    prefix: classpath:/templates/
    suffix: .html
    encoding: UTF-8
    check-template-location: true
    servlet:
      content-type: text/html
    mode: HTML
    cache: false

创建一个User对象

package com.dfyang.staticizepage.pojo;

/**
 * 用户
 */
public class User {

    private String username;

    private String password;

    public User() {
    }

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

创建一个动态页面(这里用到了themeleaf,其他的也无所谓)

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>用户</title>
</head>
<body>
    <table>
        <tr>
            <td>用户名:</td>
            <td th:text="${user.username}"></td>
        </tr>
        <tr>
            <td>密码:</td>
            <td th:text="${user.password}"></td>
        </tr>
    </table>
</body>
</html>

创建controller层

package com.dfyang.staticizepage.controller;

import com.dfyang.staticizepage.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class UserController {

    @GetMapping("/user")
    public String user(Model model) {
        // 模拟从数据库中查询用户
        User user = new User("user", "upass");
        model.addAttribute("user", user);
        return "/user";
    }

}

启动项目,访问 http://localhost:8080/user
下面显示的就是要生成的静态页面,非常的简单,真实生成的可能有非常多的图片和文字,如果并发量大的化,会占用较大的网络服务器带宽,所以需要页面静态化处理。(注意:页面的多少与静态化步骤没有任何关系)
在这里插入图片描述
创建StaticizePageUtil工具类,生成静态页面的具体逻辑

package com.dfyang.staticizepage.utils;

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.util.ResourceUtils;
import java.io.*;

/**
 * 静态化页面工具类
 */
public class StaticizePageUtil {

    /** 生成静态文件的根路径 */
    private static String basePath;

    static {
        try {
            basePath = ResourceUtils.getFile("classpath:templates").getAbsolutePath() + "\\static\\";
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }


    /**
     * 生成静态页面
     * @param url 生成静态页面的url
     * @param filePath 生成静态页面的路径
     */
    public static void staticize(String url, String filePath) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);
        CloseableHttpResponse response = null;
        HttpEntity entity = null;
        Writer writer = null;
        try {
            // 1) 通过HttpClient访问url
            response = httpClient.execute(httpGet);
            entity = response.getEntity();
            if (entity != null) {
                String entityStr = EntityUtils.toString(entity); // 将请求获取到的页面信息转换为字符串
                File file = new File(basePath + filePath);
                System.err.printf(basePath + filePath); // 这里将路径输出一下
                File baseDirs = new File(basePath);
                if (!baseDirs.exists())
                    baseDirs.mkdirs(); // 如果生成文件夹不存在则创建
                if (!file.exists())
                    file.createNewFile(); // 如果目标文件夹不存在则创建
                writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));
                // 2) 将访问url获取的内容输出到指定文件
                writer.write(entityStr);
                writer.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 3) 关闭资源
            try {
                if (entity != null)
                    EntityUtils.consume(entity);
                if (writer != null)
                    writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

注意:如果是webapp/WEB-INF/目录的,可以通过
request.getSession().getServletContext().getRealPath("/WEB-INF/jsp/user/");进行获取。
request可以通过@Autowired private HttpServletRequest request直接注入,传递也行,这里很好改就不演示了。
可以在controller层添加下面方法,访问 http://localhost:8080/generate

	@GetMapping("/generate")
    @ResponseBody
    public String generate() {
        StaticizePageUtil.staticize("http://localhost:8080/user", "user.html");
        return "生成静态页面成功";
    }

到这里已经生成好了静态文件,那么如何让用户访问静态页面
只需要改写controller,让用户直接访问静态页面,而真正访问数据源的让HttpClient进行访问

    @GetMapping("/user")
    public String user(Model model) {
        return "/static/user";
    }
    
    @GetMapping("/staticizeUser")
    public String staticizeUser(Model model) {
        // 模拟从数据库中查询用户
        User user = new User("user", "upass");
        model.addAttribute("user", user);
        return "/user";
    }

如果页面有时会变化,我们可能需要定时去刷新我们的静态页面
在启动类上加上@EnableScheduling注解

package com.dfyang.staticizepage;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class StaticizePageApplication {

    public static void main(String[] args) {
        SpringApplication.run(StaticizePageApplication.class, args);
    }
}

修改application.yml,添加如下

custom:
  user:
    url: http://localhost:8080/user
    file: user.html

创建定时任务,这样在我们启动项目就会定时为我们刷新静态页面

package com.dfyang.staticizepage.task;

import com.dfyang.staticizepage.utils.StaticizePageUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

/**
 * 静态化用户界面
 */
@Component
public class StaticizeUserHtmlTask {

    @Value("${custom.user.url}")
    private String url;

    @Value("${custom.user.file}")
    private String file;

    @Scheduled(fixedRate = 300000)
    public void generateStaticJSP() {
        System.out.printf("生成静态页面");
        StaticizePageUtil.staticize(url, file);
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值