因?yàn)橐彩莿偪矗矝]有更深一步的了解,JSP靜態(tài)化一般用在日志、新聞的創(chuàng)建而隨之去創(chuàng)建的。而偽靜態(tài)不知是為了加密,還是流行。
呵呵,下面我說下我的做法,很簡(jiǎn)單。很適合新手。
首先是靜態(tài)化:
private static final String CONTENT_TYPE = "text/html; charset=utf-8";
public static String isStatus(String picName,String jspName,HttpSession session,HttpServletRequest request, HttpServletResponse response){
String uuid=java.util.UUID.randomUUID().toString();
session=request.getSession();
DAOFactory dao=DAOFactory.getInstance();
String name = "";
String htmlName="";
try {
response.setContentType(StatUtil.CONTENT_TYPE);
String url = "";
ServletContext sc =session.getServletContext();
// 你要訪問的jsp文件,如index.jsp
// 則你訪問這個(gè)servlet時(shí)加參數(shù).如http://localhost/toHtml?file_name=index
url = "/"+jspName;
// 這是你要生成HTML的jsp文件,如
name = request.getRealPath("/")+"pic-name-"+uuid+".html";
htmlName="pic-name-"+uuid+".html";
// 這是生成的html文件名,如index.htm.
RequestDispatcher rd = sc.getRequestDispatcher(url);
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(response) {
public ServletOutputStream getOutputStream() {
return stream;
}
public PrintWriter getWriter() {
return pw;
}
};
rd.include(request, rep);
pw.flush();
FileOutputStream fos = new FileOutputStream(name);
// 把jsp輸出的內(nèi)容寫到xxx.htm
os.writeTo(fos);
fos.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return htmlName;
}
以上是個(gè)方法,可以摘摘剪剪的放在自己的程序里。
但是要注意,request傳值,一定要放在這個(gè)上面去做,否則得話,頁(yè)面里將沒有內(nèi)容。反正我試的結(jié)果就是這樣。
下面是偽靜態(tài)。這塊我也是從網(wǎng)上摘找的工具類,試了一下,很好使,很強(qiáng)大。
第一步,創(chuàng)建兩個(gè)工具類。
代碼如下,直接粘過去就可以用了。
public class Base64Coder {
private static char[] map1 = new char[64];
static {
int i = 0;
for (char c = 'a'; c <= 'z'; c++)
map1[i++] = c;
for (char c = '0'; c <= '9'; c++)
map1[i++] = c;
for (char c = 'A'; c <= 'Z'; c++)
map1[i++] = c;
map1[i++] = '+';
map1[i++] = '/';
}
private static byte[] map2 = new byte[128];
static {
for (int i = 0; i < map2.length; i++)
map2[i] = -1;
for (int i = 0; i < 64; i++)
map2[map1[i]] = (byte) i;
}
public static String encodeString(String s) {
return new String(encode(s.getBytes()));
}
public static char[] encode(byte[] in) {
return encode(in, in.length);
}
public static char[] encode(byte[] in, int iLen) {
int oDataLen = (iLen * 4 + 2) / 3; // output length without padding
int oLen = ((iLen + 2) / 3) * 4; // output length including padding
char[] out = new char[oLen];
int ip = 0;
int op = 0;
while (ip < iLen) {
int i0 = in[ip++] & 0xff;
int i1 = ip < iLen ? in[ip++] & 0xff : 0;
int i2 = ip < iLen ? in[ip++] & 0xff : 0;
int o0 = i0 >>> 2;
int o1 = ((i0 & 3) << 4) | (i1 >>> 4);
int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6);
int o3 = i2 & 0x3F;
out[op++] = map1[o0];
out[op++] = map1[o1];
out[op] = op < oDataLen ? map1[o2] : '_';
op++;
out[op] = op < oDataLen ? map1[o3] : '_';
op++;
}
return out;
}
public static String decodeString(String s) {
return new String(decode(s));
}
public static byte[] decode(String s) {
return decode(s.toCharArray());
}
public static byte[] decode(char[] in) {
int iLen = in.length;
if (iLen % 4 != 0)
throw new IllegalArgumentException(
"Length of Base64 encoded input string is not a multiple of 4.");
while (iLen > 0 && in[iLen - 1] == '_')
iLen--;
int oLen = (iLen * 3) / 4;
byte[] out = new byte[oLen];
int ip = 0;
int op = 0;
while (ip < iLen) {
int i0 = in[ip++];
int i1 = in[ip++];
int i2 = ip < iLen ? in[ip++] : 'A';
int i3 = ip < iLen ? in[ip++] : 'A';
if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127)
throw new IllegalArgumentException(
"Illegal character in Base64 encoded data.");
int b0 = map2[i0];
int b1 = map2[i1];
int b2 = map2[i2];
int b3 = map2[i3];
if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0)
throw new IllegalArgumentException(
"Illegal character in Base64 encoded data.");
int o0 = (b0 << 2) | (b1 >>> 4);
int o1 = ((b1 & 0xf) << 4) | (b2 >>> 2);
int o2 = ((b2 & 3) << 6) | b3;
out[op++] = (byte) o0;
if (op < oLen)
out[op++] = (byte) o1;
if (op < oLen)
out[op++] = (byte) o2;
}
return out;
}
private Base64Coder() {
}
}
-----------------------------------------------------------------------------------------------
import java.util.*;
public class HtmlUtil {
protected static int JSP=20091;
protected static int ACTION=20092;
protected static int HTML=20093;
protected static int SEALED=404;
protected static String propertyName;//項(xiàng)目名稱以及 前面得 那段文件夾路徑
protected static String actionName;//action的名稱
protected static String operate;//action執(zhí)行的方 或則 jsp頁(yè)面的名稱
protected static int type;//類型
protected static HashMap<String, String> items=new HashMap<String, String>();
/**
* 把真實(shí)得url轉(zhuǎn)換為html路徑 (例:/Shopping/user.do?operate=doLogin&userName=xiaowu&password=19890104)
*/
public static synchronized String getHtmlUrl(String url){
//判斷類型
type=getType(url);
propertyName=getPropertyName(url);
//如果是一個(gè)ACTION
if(type==ACTION){
actionName=getActionName(url,true);
operate=getFunctionName(url,true);
items=getItems(url,true);
}
if(type==JSP){
actionName=getJspName(url,true);
items=getItems(url,true);
}
//創(chuàng)建URL
return createHtmlUrl();
}
/**
* 創(chuàng)建Html路徑
* @return
*/
protected static String createHtmlUrl(){
StringBuffer newUrl=new StringBuffer("");
newUrl.append(actionName);
newUrl.append("_");
if(operate!=null&&!operate.equals("")){
newUrl.append(operate);
}
newUrl.append("_");
newUrl.append(type);
newUrl.append("_");
Set<String> keys=items.keySet();
for (Object key : keys) {
newUrl.append(key+"_"+items.get(key)+"_");
}
//對(duì)字符串進(jìn)行編碼
String coding=Base64Coder.encodeString(newUrl.toString());
if(propertyName!=null&&!propertyName.equals("")){
return propertyName+coding+".html";
}
return coding+".html";
}
/**
* 把html路徑轉(zhuǎn)換為真實(shí)的路徑
*/
public static synchronized String getRealityUrl(String url){
//判斷類型
type=getType(url);
if(type==JSP||type==ACTION){
//路徑為加密就直接返回
return url;
}
propertyName=getPropertyName(url);
String newUrl="";
if(type==HTML){
try{
newUrl=url.substring(url.lastIndexOf("/")+1,url.length()-5);
//對(duì)字符串進(jìn)行解碼
newUrl=Base64Coder.decodeString(newUrl);
actionName=getActionName(newUrl, false);
operate=getFunctionName(newUrl,false);
items=getItems(newUrl,false);
type=getUrlType(newUrl);
}catch(Exception ee){
//如果是html頁(yè)面強(qiáng)制改為jsp
if(url.substring(url.length()-5).equalsIgnoreCase(".html")){
//newUrl被改寫過 所有要重新取得
newUrl=url.substring(url.lastIndexOf("/")+1,url.length()-5);
return newUrl+".jsp";
}
//如果URL無(wú)法通過解碼那么就直接返回
return url;
}
}
return createRealityUrl();
}
// /**
// * 動(dòng)態(tài)創(chuàng)建
// */
// public static synchronized String getHtmlUrl(String url,boolean b){
// if(b==true){
// if(url.indexOf("?")==-1){
// url+="?";
// url+="id"+System.currentTimeMillis()+"="+new Random().nextFloat();
// }else{
// url+="&id"+System.currentTimeMillis()+"="+new Random().nextFloat();
// }
// }
// return getHtmlUrl(url);
// }
/**
* 還原真實(shí)路徑
* @return
*/
protected static String createRealityUrl(){
StringBuffer newUrl=new StringBuffer("");
if(propertyName!=null&&!propertyName.equals("")){
newUrl.append(propertyName);
}
if(actionName!=null&&!actionName.equals("")){
if(type==ACTION){
if(!operate.equals("")){
newUrl.append(actionName+".do?operate="+operate);
}else{
newUrl.append(actionName+".do");
}
}else if(type==JSP){
newUrl.append(actionName+".jsp");
}else if(type==HTML){
newUrl.append(actionName+".html");
}else{
newUrl.append(actionName);
}
}
Set<String> keys=items.keySet();
boolean isInterrogation=newUrl.toString().indexOf("?")!=-1?true:false;
for (Object key : keys) {
if(isInterrogation==false){
newUrl.append("?");
isInterrogation=true;
}else{
newUrl.append("&");
}
newUrl.append(key+"="+items.get(key));
}
return newUrl.toString();
}
// public static void main(String[] args) {
// String strs[]={"/Shopping/user.do?operate=doLogin&userName=xiaowu&password=19890104",
// "/Shopping/user.jsp?userName=xiaowu&password=19890104",
// "user.do?operate=doLogin&userName=xiaowu&password=19890104",
// "user.jsp?userName=xiaowu&password=19890104",
// "/user.do?operate=doLogin&userName=xiaowu&password=19890104",
// "/user.jsp?userName=xiaowu&password=19890104",
// "user.do?operate=doLogin",
// "/user.jsp",
// "/Shopping/user.do",
// "/Shopping/user.jsp",
// "user.do",
// "/user.do",
// "user.jsp",
// "/user.jsp",
// "/Shopping/MyJsp.jsp"};
// for (int i = 0; i < strs.length; i++) {
// System.err.println("原路徑"+strs[i]);
// String str=HtmlUtil.getHtmlUrl(strs[i]);
// System.err.println("加密后"+str);
// str=HtmlUtil.getRealityUrl(str);
// System.err.println("還原后"+str);
// System.err.println("-----------------------------------------");
// }
// }
/**
* 返回類型
*/
protected static int getUrlType(String url){
if(url.indexOf("__")!=-1){
return Integer.parseInt(getStr(url,1,"_"));
}
return Integer.parseInt(getStr(url,2,"_"));
}
/**
* 返回項(xiàng)目名稱
*/
protected static String getPropertyName(String url){
if(url.indexOf("/")==-1){
return "";
}
return url.substring(0,url.lastIndexOf("/")+1);
}
/**
* 返回ACTION名稱
*/
protected static String getActionName(String url,boolean b){
if(b==false){
return getStr(url,0,"_");
}
if(url.indexOf("/")==-1){
return url.substring(0,url.indexOf("."));
}
return url.substring(url.lastIndexOf("/")+1,url.indexOf("."));
}
/**
* 返回JSP名稱
*/
protected static String getJspName(String url,boolean b){
if(url.indexOf("/")==-1){
return url.substring(0,url.indexOf("."));
}
return url.substring(url.lastIndexOf("/")+1,url.indexOf("."));
}
/**
* 返回方法名稱
*/
protected static String getFunctionName(String url,boolean b){
if(b==false){
if(url.indexOf("__")!=-1){
return "";
}
return getStr(url,1,"_");
}
if(url.indexOf("?")==-1)
return "";
url=url.substring(url.lastIndexOf("operate=")+8,url.length());
if(url.indexOf("&")==-1){
return url;
}
return url.substring(0,url.indexOf("&"));
}
/**
*
*/
protected static String getStr(String str,int count,String condition){
java.util.StringTokenizer tok=new StringTokenizer(str,condition);
int index=0;
while(tok.hasMoreElements()){
String newStr=tok.nextElement().toString();
if(index==count){
return newStr;
}
index++;
}
return "";
}
/**
* 返回items
*/
protected static HashMap<String, String> getItems(String url,boolean b){
HashMap<String, String> items=new HashMap<String, String>();
if(b==false){
java.util.StringTokenizer tok=new StringTokenizer(url,"_");
int index=0;
if(url.indexOf("__")!=-1){
index++;
}
while(tok.hasMoreElements()){
String newStr=tok.nextToken();
if(index>=3){
String key=newStr;
String value=null;
try {
value=tok.nextToken();
} catch (Exception e) {
value="";
}
items.put(key, value);
}
index++;
}
return items;
}
url=url.substring(url.lastIndexOf("?")+1,url.length());
java.util.StringTokenizer tok=new StringTokenizer(url,"&");
while(tok.hasMoreElements()){
String str=tok.nextToken();
if(str.indexOf("operate=")==-1&&str.indexOf("=")!=-1){
StringTokenizer newTok=new StringTokenizer(str,"=");
if(newTok.hasMoreElements()){
String key=newTok.nextToken();
newTok.hasMoreElements();
String value=null;
try {
value=newTok.nextToken();
if(value.equals("")){
value=null;
}
} catch (Exception e) {
value=null;
}
if(key.equals("")){
key=null;
}
items.put(key, value);
}
}
}
return items;
}
/**
* 判斷類型
*/
protected static int getType(String url){
if(url.toUpperCase().indexOf(".DO")!=-1){
return ACTION;
}else if(url.toUpperCase().indexOf(".JSP")!=-1){
return JSP;
}else if(url.toUpperCase().indexOf(".HTML")!=-1){
return HTML;
}else{
return SEALED;
}
}
}
------------------------------------------
第二步,創(chuàng)建一個(gè)servlet。嗯,我的程序時(shí)用status做的,只要在web.xml里面添加一個(gè)servlet標(biāo)簽就可以了。如下:
<servlet>
<servlet-name>HtmlDecode</servlet-name>
<servlet-class>
com.clothes.util.statUtil.HtmlDecode ///////這是你的servlet的位置
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HtmlDecode</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
///這是讓你的所有以*.html跳轉(zhuǎn)都跑到這個(gè)servlet里面,當(dāng)然,也可以改成別的。都可以的。只要在htmlUtil類里去修改一下就可以了。用起來(lái)很舒服的。
第三步,就是使用咯。很簡(jiǎn)單,如下:
<A href="<%=HtmlUtil.getHtmlUrl("findProject.do?goodsid=123“)%>" >啦啦啦</a>
直接使用HtmlUtil里面的getHtmlUrl方法,他會(huì)在servlet編譯的時(shí)候,將你要跳轉(zhuǎn)的地址欄加密,同時(shí)在提交的時(shí)候,先跑到我們上面配置的哪個(gè)servlet里面,進(jìn)行解密,然后跳轉(zhuǎn)到你的.do或者其他的里面。挺好用的,不過一定要注意一點(diǎn),就是那個(gè)goodsid這最好別加“_”,前面也最好別加。否則得話,就不靈了。嗯,這也是親身經(jīng)歷。當(dāng)然,這個(gè)傳中文。。。我先試下!
嗯,不錯(cuò),剛試了<a>提交和表單提交。結(jié)果是都可以的。如果用<a>提交出現(xiàn)亂碼的話,就用我之前發(fā)的那個(gè)轉(zhuǎn)亂碼的工具類轉(zhuǎn)一下就好了。可以支持中文
可以了。以上就這些,希望可以對(duì)大家有些幫助。
哎呀。。發(fā)現(xiàn)servlet忘了寫進(jìn)去了?,F(xiàn)在加上,第二步的servlet:
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import util.*;
public class HtmlDecode extends HttpServlet {
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setCharacterEncoding("GBK");
request.setCharacterEncoding("GBK");
//取出URL
String url=request.getRequestURI();
//對(duì)URL進(jìn)行解碼
String newUrl=HtmlUtil.getRealityUrl(url);
System.out.println(newUrl);
newUrl=newUrl.replaceAll(request.getContextPath()+"/", "");
//跳轉(zhuǎn)到解碼后的頁(yè)面
request.getRequestDispatcher(newUrl).forward(request, response);
}
}
OK。就是這些。