1.背景
往往首页是包含多很内容的,对于讲究首页访问速度。动态请求生成jsp页面,往往略显吃力,这样对于服务器和db都有很大的压力。
为此,通过定时器定时请求生成静态页面,进行定时更新。
2.实现逻辑
我们需要解决下面一些技术问题:
一、静态请求的逻辑:
1.拼装jsp请求,发送请求2.将请求到的结果进行流输出,jsp->html的转换过程
额外需求:
定时调用生成静态页面
问题:
1.如何知道jsp请求?
查看配置文件便可知道
2.如何发送jsp请求?
转发即可(保留request,response)
----------------------------------------
1.如何将请求的结果保存并进行流输出?
虽然有源码,但还是不怎么清楚原理
二、如何让其定时的自动发送生成静态页面的请求?
1.使用URLConnection进行发送请求(携带必要参数)2.使用Timer进行定时访问
3.使用wrapper生成后台服务,自动发送请求
3.实现源码
-------------------------------------------web端-------------------------------------------------------------------
1.生成静态页面的servlet请求源码-ToHtmlServlet
public class ToHtmlServlet extends HttpServlet {
/**
* 需要转换成静态页面的动态请求,相对路径(request)
*/
private String url = "";
/**
* 生成的静态文件的绝对路径
*/
private String path = "";
/**
* 需要转换成静态页面的动态请求名称(ps:不需要添加do后缀)
*/
private String actionName="";
/*
* (non-Javadoc)
*
* @see
* javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest
* , javax.servlet.http.HttpServletResponse)
*/
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 则你访问这个servlet时加参数.如http://localhost/test/toHtml?actionName=index
actionName = req.getParameter("actionName");// 你要访问的jsp文件名,如index,不包括扩展名
url = "/" + actionName + ".do";
path = this.getServletContext().getRealPath("/") + "index.htm";
// 这是生成的html文件名,如index.htm.文件名字与源文件名相同。扩展名为htm
RequestDispatcher rd = req.getRequestDispatcher(url);
// 通过匿名类来创建一个stream实例,只引用其中write方法
// 通过匿名类创建PrintWriter实例,使用上面输出客户端的流stream
// 通过自定义实例化pw对象
/**
* 个人觉得产生的匿名产生的stream和rep以及新实例化的pw对象,都与本身此请求的steam,rep,pw对象完全不同。
* 这些自定产生的对象是用于保存流并输出到指定的静态文件。
*/
// 静态处理开始....
final ByteArrayOutputStream os = new ByteArrayOutputStream();
final ServletOutputStream stream = new ServletOutputStream() {
public void write(byte[] data, int offset, int length) {
os.write(data, offset, length);
}
public void write(int b) throws IOException {
os.write(b);
}
};
final PrintWriter pw = new PrintWriter(new OutputStreamWriter(os));
HttpServletResponse rep = new HttpServletResponseWrapper(resp) {
public ServletOutputStream getOutputStream() {
return stream;
}
public PrintWriter getWriter() {
return pw;
}
};
// 用来记录保留request和response,以后不能再修改response里表示状态的信息
rd.include(req, rep);
pw.flush();
FileOutputStream fos = new FileOutputStream(path); // 把jsp输出的内容写到xxx.htm
os.writeTo(fos);
fos.close();
// 静态处理结束...
// 下面是针对此请求对应客户端的响应方式
resp.setCharacterEncoding("utf8");
PrintWriter out = resp.getWriter();
out.print("生成成功~");
}
}
2.需要生成静态页面的动态请求-IndexServlet(url)
public class IndexServlet extends HttpServlet {
/* (non-Javadoc)
* @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
RequestDispatcher rd=req.getRequestDispatcher("template.jsp");
rd.forward(req, resp);
}
}
3.web.xml配置详情
<servlet>
<servlet-name>toHtml</servlet-name>
<servlet-class>com.techbirds.servlet.ToHtmlServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>toHtml</servlet-name>
<url-pattern>/toHtml.do</url-pattern>
</servlet-mapping>
<!-- 需要静态的首页请求 -->
<servlet>
<servlet-name>toIndex</servlet-name>
<servlet-class>com.techbirds.servlet.IndexServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>toIndex</servlet-name>
<url-pattern>/toIndex.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>toIndexHtm.jsp</welcome-file>
</welcome-file-list>
4.jsp页面列表
-------------------------------------------定时服务端-------------------------------------------------------------------
5.发送请求-Service
public class CallHtmlService {
public void callHtml(String actionName) {
try {
String str = "http://localhost:8080/toHtml/toHtml.do?actionName="
+ actionName;
int httpResult;
URL url = new URL(str);
URLConnection connection = url.openConnection();
connection.connect();
HttpURLConnection httpURLConnection = (HttpURLConnection) connection;
httpResult = httpURLConnection.getResponseCode();
if (httpResult != HttpURLConnection.HTTP_OK) {
System.out.println("生成失败...");
} else {
System.out.println("生成成功...");
}
} catch (Exception e) {
}
}
}
6.定时任务
public class CallHtmlTimer {
/**
* 延迟几秒执行
*/
private static Long DELAYTIME=1000*10l;
/**
* 间隔几秒执行
*/
private static Long PERIODTIME=1000*10l;
public static void main(String[] args) {
Timer timer=new Timer();
timer.schedule(new CallHtmlTask(), DELAYTIME, PERIODTIME);
}
}
class CallHtmlTask extends TimerTask{
@Override
public void run() {
new CallHtmlService().callHtml("toIndex");
}
}
ps:做成windows服务参考: http://blog.csdn.net/techbirds_bao/article/details/8799528