spc

Similar documents
1.JasperReport ireport JasperReport ireport JDK JDK JDK JDK ant ant...6

(TestFailure) JUnit Framework AssertionFailedError JUnit Composite TestSuite Test TestSuite run() run() JUnit

新・解きながら学ぶJava

エスポラージュ株式会社 住所 : 東京都江東区大島 東急ドエルアルス大島 HP: ******************* * 关于 Java 测试试题 ******

JavaIO.PDF

Servlet

D getinitparameternames() 9 下 列 选 项 中, 属 于 Servlet API 中 提 供 的 request 对 象 的 包 装 类 的 是 ( ) A HttpServletRequestWrapper B HttpServletRequest C HttpServ

Microsoft Word - 01.DOC

untitled

chp6.ppt

没 有 多 余 的 Contruol 或 Action 了 原 来 Domain 层 被 服 务 层 Service layer 遮 挡, 在 右 边 图 中, 则 Domain 层 直 接 暴 露 给 前 台 了, 没 有 被 遮 挡, 裸 露 了 这 样 一 步 到 位 实 现 领 域 模 型

EJB-Programming-4-cn.doc

获取 Access Token access_token 是接口的全局唯一票据, 接入方调用各接口时都需使用 access_token 开发者需要进行妥善保存 access_token 的存储至少要保留 512 个字符空间 access_token 的有效期目前为 2 个小时, 需定时刷新, 重复

<4D F736F F F696E74202D20332D322E432B2BC3E6CFF2B6D4CFF3B3CCD0F2C9E8BCC6A1AAD6D8D4D8A1A2BCCCB3D0A1A2B6E0CCACBACDBEDBBACF2E707074>

resp.getwriter().print(j + "*" + i + "=" + j * i+" "); resp.getwriter().print("<br/>"); protected void dopost(httpservletrequest req, HttpServletRespo

Microsoft Word - 第3章.doc

untitled

使用 Eclipse 开发 Java EE 应用 (Web 应用 ) 这里以开发一个简单的 Web 应用为例, 介绍使用 Eclipse 开发 Java EE 应用的一般步 骤 此处使用的 Eclipse 是 Eclipse IDE for Java EE Developers; 如果是使用的其他

Java java.lang.math Java Java.util.Random : ArithmeticException int zero = 0; try { int i= 72 / zero ; }catch (ArithmeticException e ) { // } 0,

Java

詞 彙 表 編 號 詞 彙 描 述 1 預 約 人 資 料 中 文 姓 名 英 文 姓 名 身 份 證 字 號 預 約 人 電 話 性 別 2 付 款 資 料 信 用 卡 別 信 用 卡 號 信 用 卡 有 效 日 期 3 住 房 條 件 入 住 日 期 退 房 日 期 人 數 房 間 數 量 入

Microsoft Word - ch04三校.doc

OOP with Java 通知 Project 4: 4 月 19 日晚 9 点

基于CDIO一体化理念的课程教学大纲设计

雲端 Cloud Computing 技術指南 運算 應用 平台與架構 10/04/15 11:55:46 INFO 10/04/15 11:55:53 INFO 10/04/15 11:55:56 INFO 10/04/15 11:56:05 INFO 10/04/15 11:56:07 INFO

《大话设计模式》第一章

Guava学习之Resources

1 1 大概思路 创建 WebAPI 创建 CrossMainController 并编写 Nuget 安装 microsoft.aspnet.webapi.cors 跨域设置路由 编写 Jquery EasyUI 界面 运行效果 2 创建 WebAPI 创建 WebAPI, 新建 -> 项目 ->


Chapter 9: Objects and Classes

Microsoft PowerPoint - 04-Request-Headers-Chinese.ppt

主程式 : public class Main3Activity extends AppCompatActivity { ListView listview; // 先整理資料來源,listitem.xml 需要傳入三種資料 : 圖片 狗狗名字 狗狗生日 // 狗狗圖片 int[] pic =new

新版 明解C++入門編

1: public class MyOutputStream implements AutoCloseable { 3: public void close() throws IOException { 4: throw new IOException(); 5: } 6:

威 福 髮 藝 店 桃 園 市 蘆 竹 區 中 山 里 福 祿 一 街 48 號 地 下 一 樓 50,000 獨 資 李 依 純 105/04/06 府 經 登 字 第 號 宏 品 餐 飲 桃 園 市 桃 園 區 信 光 里 民

untitled

javaexample-02.pdf

前言 C# C# C# C C# C# C# C# C# microservices C# More Effective C# More Effective C# C# C# C# Effective C# 50 C# C# 7 Effective vii

SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 "odps-sdk" 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基

untitled

<ADB6ADB1C25EA8FAA6DB2D4D56432E706466>

JBuilder Weblogic

天仁期末個人報告1.PDF

第3章.doc

<4D F736F F D20C8EDC9E82DCFC2CEE7CCE22D3039C9CF>

Swing-02.pdf

全国计算机技术与软件专业技术资格(水平)考试

untitled

9, : Java 19., [4 ]. 3 Apla2Java Apla PAR,Apla2Java Apla Java.,Apla,,, 1. 1 Apla Apla A[J ] Get elem (set A) A J A B Intersection(set A,set B) A B A B

OOP with Java 通知 Project 4: 5 月 2 日晚 9 点


用手機直接傳值不透過網頁連接, 來當作搖控器控制家電 ( 電視遙控器 ) 按下按鍵發送同時會回傳值來確定是否有送出 問題 :1. 應該是使用了太多 thread 導致在傳值上有問題 2. 一次按很多次按鈕沒辦法即時反應

OOP with Java 通知 Project 3: 3 月 29 日晚 9 点 4 月 1 日上课

untitled

jsp

Microsoft Word - Broker.doc

使用MapReduce读取XML文件

java2d-4.PDF

建立Android新專案

Microsoft Word - 第4章 Servlet开发—教学设计.doc

電機工程系認可證照清單 /7/1

KillTest 质量更高 服务更好 学习资料 半年免费更新服务

untitled

javascript sdk javascript sdk 列出 Bucket 内的对象上传 textarea 内容到 Bucket 上传本地文件生成私有下载链接生成带过期时间的私有链接删除对象下载对象拷贝对象查看文件访问权限设置文件访问权限获取静态网站配置设置静态网站删除静态网站查询对象元数据查询

untitled

秘密


3.1 num = 3 ch = 'C' 2

CHAPTER VC#

(Microsoft Word - \244g\246a\247B\244\275\253H\245\365\244\247\275\325\254d\254\343\250s doc)

Transcription:

网站的静态页面生成方案 yanrong79@gmail.com 提升网站性能的方式有很多, 例如有效的使用缓存, 生成静态页面等等 今天要说的就是生成静态页面的方式 什么叫生成静态页面呢? 很简单, 例如我们如果访问一个链接 http://xyz.com/index.do, 那么服务器就会解析这个请求, 让特定的 Action 去处理 这其中的缺点是显而易见的 : 如果访问的人, 那么就会加重应用服务器的压力, 最恶劣的后果就是应用服务器 down 掉了 那么如何去避免呢? 如果我们把对 index.do 请求后的结果保存成一个 html 文件, 然后每次用户都去访问 http://xyz.com/index.html, 这样应用服务器的压力不就减少了? 好吧, 我已经学会如何生成静态页面了 打开我的浏览器, 输入 http://xyz.com/index.do, 然后再使用 另存为 功能保存一个 html 文件, 然后上传到服务器, 这样就 ok 了! 我不能说这不是解决方案, 但是我可以说这不是好的解决方案 我们需要的是自动的生 成静态页面, 当用户访问 http://xyz.com/index.do, 会自动生成 index.html, 然后显示给 用户 1 基础 URL Rewrite 什么是 URL Rewrite 呢? 请 google it 不过这里简单的啰嗦一下 从字面上我们就可以理解它的意思 :URL 重写 用一个简单的例子来说明问题 : 输入网址 http://www.xyz.com/index.do, 但是实际上访问的却是 http://www.xyz.com/index.action, 那我们就可以说 URL 被重写了 这项技术应用广泛, 有许多开源的工具可以实现这个功能 2 基础 Servlet web.xml 如果你还不知道 web.xml 中一个请求和一个 servlet 是如何匹配到一起的, 那么请搜索一下 servlet 的文档 这可不是乱说呀, 有很多人就认为 /xyz/*.do 这样的匹配方式能有效 如果你还不知道怎么编写一个 servlet, 那么请搜索一下如何编写 servlet 这可不是说笑呀, 在各种集成工具漫天飞舞的今天, 很多人都不会去从零编写一个 servlet 了 3 谈谈方法 好了, 现在步入正题 谈谈生成静态页面的方法 ( 还是不要说成 原理, 给人一种

很高深的感觉 ) 方法就是这样 : 请求 index URL Rewriter 请求 index.action 处理.action 的 servlet 显示静态页面 如果静态页面 存在 请求 index.do Struts servlet 生成静态页面 显示静态页面 方法 1 其中, 对于 URL Rewriter 的部分, 可以使用收费或者开源的工具来实现, 如果 url 不是特别的复杂, 可以考虑在 servlet 中实现, 那么就是下面这个样子 :

请求 index.action 处理.action 的 servlet 显示静态页面 如果静态页面 存在 URL Rewriter 请求 index.do Struts servlet 否则生成静态页面 显示静态页面 方法 2 图画的有些乱, 不过方法还是非常简单, 其中最关键的有 2 个地方 :1 是 url rewriter, 2 是生成静态页面的具体代码 4 从一个简单的方式入手 现在我们从一个简单的方式入手来看看怎么生成静态页面 假如现在要显示第一页的商品, 那么通常的链接会是这个样子 : http://xyz.com/product.do?pagenumber=1 好, 我们说了使用最简单的方式, 那么我们就不使用 url rewriter 工具了, 我们来做一个约定 : 当我们访问 http://xyz.com/product_pagenumber_1.shtml 的时候, 就是在访问 http://xyz.com/product.do?pagenumber=1 规律就是请求的 action, 和参数的名称, 参数的值, 都用下滑线分开, 而且请求的网页是.shtm 仅仅有这样的约定还

不够, 我们还得编写一个 servlet, 去处理.shtm 的请求 : <servlet> <servlet-name>htmlcreator</servlet-name> <servlet-class>web.hc.htmlcreatorservlet</servlet-class> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>htmlcreator</servlet-name> <url-pattern>*.shtm</url-pattern> </servlet-mapping> 下面就是 servlet 的内容了 : public class HtmlCreatorServlet extends HttpServlet { private static final long serialversionuid = 1L; private Logger logger=logger.getlogger(htmlcreatorservlet.class); public void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { dopost(request, response); public void dopost(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { // 编码方式, 可以配置到 web.xml 里 String encoding = UTF-8 ; // 得到真实的请求地址 String templatepath = simpleurlrewrite(request); String realpath= request.getsession().getservletcontext().getrealpath("/"); // 想要生成的静态 html 文件的名字 String htmlname = gethtmlfilename(request);

// 静态 html 的名字, 包含绝对路径 String cachfilename = realpath + File.separator + htmlname; logger.debug("cachfilename = " + cachfilename); File cachefile = new File(cachFileName); boolean load = true; // 如果静态 html 存在, 就直接显示 html, 否则, 我们就生成它 if(cachefile.exists()) { load = false; if(load) { 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, encoding)); HttpServletResponse rep = new HttpServletResponseWrapper(response) { public ServletOutputStream getoutputstream() { return stream; public PrintWriter getwriter() { return pw;

; logger.debug("htmlcreatorservlet RequestDispatcher = " + templatepath); // 使用 RequestDispatcher 去处理真正的请求 // 例如 index.shtm, 则转发到 index.do RequestDispatcher dispatcher = getservletcontext().getrequestdispatcher(templatepath); dispatcher.include(request, rep); pw.flush(); FileOutputStream fos = null; try { if(os.size() == 0) { // 如果请求的地址无效, 那么就发送一个 404 错误 response.senderror( HttpServletResponse.SC_NOT_FOUND, ""); else { // 生成静态文件, 并且显示这个静态文件 fos = new FileOutputStream(cachFileName); os.writeto(fos); dispatcher = getservletcontext(). getrequestdispatcher("/"+htmlname); dispatcher.include(request, response); finally { if(fos!= null) { fos.close(); else { RequestDispatcher dispatcher = getservletcontext().getrequestdispatcher("/"+htmlname);

dispatcher.include(request, response); // 这个方法就是把 http://xyz.com/product_pagenumber_1.shtm // 变成 http://xyz.com/product.do?pagenumber=1 protected String simpleurlrewrite(httpservletrequest request) throws ServletException, IOException { String uri = request.getrequesturi(); String contextpath = request.getcontextpath(); logger.debug("htmlcreator contextpath = " + contextpath); if (contextpath!= null && contextpath.length() > 0) uri = uri.substring(contextpath.length()); uri = uri.substring(0, uri.length()-5); String[] urls = uri.split("_"); uri = urls[0] + ".do"; if(urls.length > 1) { for(int i = 1; i < urls.length; i += 2) { if(i==1) { uri += "?" + urls[i] + "=" + urls[i+1]; else { uri += "&" + urls[i] + "=" + urls[i+1]; logger.debug("htmlcreatorservlet get uri = " + uri); return uri; // 这个方法就是根据 http://xyz.com/product_pagenumber_1.shtm // 来得到生成的 html 文件名字, 也就是 product_pagenumber_1.html private String gethtmlfilename(httpservletrequest request) throws ServletException, IOException{

String uri = request.getrequesturi(); String contextpath = request.getcontextpath(); if (contextpath!= null && contextpath.length() > 0) uri = uri.substring(contextpath.length()); uri = uri.substring(1, uri.length()-5); uri += ".html"; return uri; 真是简单的不能再简单了! 我们这个 servlet 其实什么也没有做, 因为真正的请求我 们已经转发给 struts 了 5 请遵守访问方式? 上面我们已经知道, 如果用户访问 product_pagenumber_1.shtm, 那么我们可以保证让用户访问静态页面, 从而减轻应用服务器的压力 可是如果客户直接访问 index.do?pagenumber=1 呢? 难道我们要在页面上告诉访问者 请遵守访问方式, 否则您将被如何如何 吗? 看来我们需要在 index.do 中做点手脚 如果 index.do 中能够知道当前的请求是从 index.shtm 传过来, 而不是直接从浏览器中传过来不就好了? 我们可以在 index.shtm 的 servlet 里设置一个变量, 然后在 index.do 的 action 中检查这个变量是否存在 实现方式就不罗嗦了, 因为实在是太容易了! 6 为什么没有使用 URL Rewriter? 上面的例子没有使用 URL Rewriter! 但是请看看 simpleurlrewrite 这个方法, 如果网站的应用不复杂, 那么自己编写一个满足需求的 url rewriter 也是个不错的主意 大家完全可以参考上面的实现方式, 然后再增加 url rewriter 的工具 7 怎么刷新这些静态的 html? 刷新这些静态 html, 可以考虑这么几种方式 1 手动刷新 我想这个功能是必须的 管理员增加了一个商品, 他当然可以立刻刷新静态页面了 2 定时刷新 定时刷新可以 2 种方式 一是定时刷新全部页面 这也没什么难的, 例如要刷新全部商品的页面, 你可以得到全部的商品, 分页的规则, 然后就分别发送 http 请求就可以了 二是乐观刷新 ( 我自己编造的词 ) 我仅仅刷新已经存在的 html

例如如果目录里存在 index.html, 那么我就发送 index.shtm 请求 实现的代码? 实在太简单了, 搜索 java 中如何发送 http 请求就可以了