环境Tomcat + JSE + PostgreSQL 我将分几个步骤完成对一个新闻发布系统的构建来理解JSP的一些基本使用方法! 首先我将先介绍这个新闻发布系统的基本结构 indexjsp管理员登陆界面 checkjsp验证管理员身份 mainjsp管理员添加新闻的页面 pubjsp发布信息的页面 display显示所有的新闻 而后台的程序主要有 DBjava数据库连接 MDjavaMD算法 PubBeanjava发布 CheckBeanjava核实登陆身份 即当你从index > main > display 走一趟你基本就可以完成一个新闻发布系统的基本功能了! 我并非把新闻的标题和内容都写入数据库因为那样太耗费数据库系统的资源而且在访问的时候总要读取数 据库很费劲我把新闻写入了一个单独的HTM文件之后把标题及HTM文件的名字写入的数据库! 而这个HTM文件的名字怎么随机生成呢?我选择了MD算法因为每个新闻的标题都不会相同所以保证了唯一 性! 下面我先把这个系统的基本框架勾勒出来说的大一点这似乎就是这个“系统”的“内核”啦!:) ================数据库部分================== CREATE TABLE administrator ( admin char() "password" char() ) WITHOUT OIDS; ALTER TABLE administrator OWNER TO admin; CREATE TABLE news ( title char() page char() ) WITHOUT OIDS; ALTER TABLE news OWNER TO admin; ================程序部分================== package login;
import javasql*; public class DB { private Connection conn; private Statement stmt; private ResultSet rs;
public DB() { try { ClassforName("orgpostgresqlDriver"); conn = DriverManagergetConnection ("jdbc:postgresql://localhost:/news?user=admin&&password="); stmt = conncreateStatement(); } catch(Exception e) { Systemoutprintln(e); } }
public void update(String sql) { try { stmtexecuteUpdate(sql); } catch(Exception e) { Systemoutprintln(e); } }
public ResultSet quarry(String sql) { try { rs = stmtexecuteQuery(sql); } catch(Exception e) { Systemoutprintln(e); } return rs; }
} package login;
import javasql*; import javaio*; public class PubBean {
private String titlecontext; private DB db; private MD md;
public PubBean() { db = new DB(); md = new MD(); }
public void setTitle(String title){ thistitle = title; }
public void setContext(String context) { thiscontext = context; } public void pubIt() { try { title = new String(titlegetBytes("_")"gb"); context = new String(contextgetBytes("_")"gb"); String titleMD = mdgetkeyBeanofStr(title); dbupdate("insert into news values("+title+""+titleMD+")"); String file = "news\\ice"+titleMD+"htm"; PrintWriter pw = new PrintWriter(new FileOutputStream(file)); pwprintln("<title>"+title+"</title>"); pwprintln(context); pwclose(); } catch(Exception e){ Systemoutprintln(e); } }
} package login;
import javasql*; public class CheckBean {
private String message=""adminpassword; private DB db;
public CheckBean() { db = new DB(); }
public void setAdmin(String admin){ thisadmin = admin; }
public void setPassword(String password) { thispassword = password; }
public String checkIt() { try { ResultSet rs = dbquarry("select * from administrator where admin="+thisadmin+""); while(rsnext()){ String pws = rsgetString("password")trim(); if(pwsequals(thispassword)){ message = "密码正确!"; } else message = "密码错误!"; return message; } message = "用户不存在!"; } catch(Exception e) { Systemoutprintln(e); } return message; }
} ================页面部分==================
indexjsp: <%@ page contentType="text/html;charset=gb"%> <html><head><title>登陆系统</title></head> <body> <form name="login" action="checkjsp" method="post"> 用户<input type="text" name="admin"><br> 密码<input type="password" name="password"><br> <input type="submit" value="登陆"><br> </form> </body> </html> <% String error=requestgetParameter("error"); error=new String(errorgetBytes("_")"gb"); if(error==null){} else{ %> <%=error%> <% } %> checkjsp <%@ page contentType="text/html;charset=gb"%> <%@ page import="loginCheckBean"%> <% String admin = requestgetParameter("admin"); String password = requestgetParameter("password"); %> <jsp:useBean id="checkBean" class="loginCheckBean"/> <jsp:setProperty name="checkBean" property="admin" value="<%= admintrim() %>"/> <jsp:setProperty name="checkBean" property="password" value="<%= passwordtrim() %>"/> <% String result = checkBeancheckIt(); if(resultequals("密码正确!")){ sessionsetAttribute("admin"admin); responsesendRedirect("mainjsp"); } else { %> <jsp:forward page="indexjsp"> <jsp:param name="error" value="<%=result%>"/> </jsp:forward> <% } %> mainjsp <%@ page contentType="text/html;charset=gb"%> <% String admin =(String)(sessiongetAttribute("admin")); if(admin==null){ responsesendRedirect("indexjsp"); } else{ %> <html><head><title>新闻发布</title></head> <body> <form name="pub" action="pubjsp" method="post"> 题目<input type="text" name="title"><br> 内容<textarea cols="" rows="" name="context"></textarea><br> <input type="submit" value="提交"><br> </form> </body> </html> <%}%> pubjsp <%@ page contentType="text/html;charset=gb"%> <% String admin = (String)(sessiongetAttribute("admin")); String title = requestgetParameter("title"); String context = requestgetParameter("context"); if(admin == null){ responsesendRedirect("indexjsp"); } else{ %> <jsp:useBean id="pubBean" class="loginPubBean"/> <jsp:setProperty name="pubBean" property="title" value="<%= titletrim() %>"/> <jsp:setProperty name="pubBean" property="context" value="<%= context %>"/> <% pubBeanpubIt(); responsesendRedirect("displayjsp"); } %> displayjsp <%@ page contentType="text/html;charset=gb"%> <%@ page import="javasql*"%> <% ClassforName("sunjdbcodbcJdbcOdbcDriver"); Connection conn=DriverManagergetConnection("jdbc:odbc:PostgreSQL"""""); Statement stmt=conncreateStatement(); %> <html><head><title>新闻</title></head> <body> <% ResultSet rs=stmtexecuteQuery("SELECT * FROM news"); //显示记录 while(rsnext()){ outprint("<a href=news/ice"+rsgetString()+"htm target=_blank>"+rsgetString ()+"</a>"); outprintln("<br>"); }%> </body> </html> 好了基本的东西都实现了希望现在已经可以给你一个完整的面貌了在后面的文章中我再把程序一步步
的完善增加一些新的功能! import javalangreflect*; public class MD { /* 下面这些SS实际上是一个*的矩阵在原始的C实现中是用#define 实现的 这里把它们实现成为static final是表示了只读切能在同一个进程空间内的多个 Instance间共享*/ static final int S = ; static final int S = ; static final int S = ; static final int S = ; static final int S = ; static final int S = ; static final int S = ; static final int S = ; static final int S = ; static final int S = ; static final int S = ; static final int S = ; static final int S = ; static final int S = ; static final int S = ; static final int S = ; static final byte[] PADDING = { }; /* 下面的三个成员是keyBean计算过程中用到的个核心数据在原始的C实现中 被定义到keyBean_CTX结构中 */ private long[] state = new long[]; // state (ABCD) private long[] count = new long[]; // number of bits modulo ^ (lsb first) private byte[] buffer = new byte[]; // input buffer /* digestHexStr是keyBean的唯一一个公共成员是最新一次计算结果的 进制ASCII表示 */ public String digestHexStr; /* digest是最新一次计算结果的进制内部表示表示bit的keyBean值 */ private byte[] digest = new byte[]; /* getkeyBeanofStr是类keyBean最主要的公共方法入口参数是你想要进行keyBean变换的字符串 返回的是变换完的结果这个结果是从公共成员digestHexStr取得的. */ public String getkeyBeanofStr(String inbuf) { keyBeanInit(); keyBeanUpdate(inbufgetBytes() inbuflength()); keyBeanFinal(); digestHexStr = ""; for (int i = ; i < ; i++) { digestHexStr += byteHEX(digest[i]); } return digestHexStr; } // 这是keyBean这个类的标准构造函数JavaBean要求有一个public的并且没有参数的构造函数 public MD() { keyBeanInit(); return; } /* keyBeanInit是一个初始化函数初始化核心变量装入标准的幻数 */ private void keyBeanInit() { count[] = L; count[] = L; ///* Load magic initialization constants
state[] = xL; state[] = xefcdabL; state[] = xbadcfeL; state[] = xL; return; } /* F G H I 是个基本的keyBean函数在原始的keyBean的C实现中由于它们是 简单的位运算可能出于效率的考虑把它们实现成了宏在java中我们把它们 实现成了private方法名字保持了原来C中的 */ private long F(long x long y long z) { return (x & y) | ((~x) & z); } private long G(long x long y long z) { return (x & z) | (y & (~z)); } private long H(long x long y long z) { return x ^ y ^ z; } private long I(long x long y long z) { return y ^ (x | (~z)); } /* FFGGHH和II将调用FGHI进行近一步变换 FF GG HH and II transformations for rounds and Rotation is separate from addition to prevent recomputation */ private long FF(long a long b long c long d long x long s long ac) { a += F (b c d) + x + ac; a = ((int) a << s) | ((int) a >>> ( s)); a += b; return a; } private long GG(long a long b long c long d long x long s long ac) { a += G (b c d) + x + ac; a = ((int) a << s) | ((int) a >>> ( s)); a += b; return a; } private long HH(long a long b long c long d long x long s long ac) { a += H (b c d) + x + ac; a = ((int) a << s) | ((int) a >>> ( s)); a += b; return a; } private long II(long a long b long c long d long x long s long ac) { a += I (b c d) + x + ac; a = ((int) a << s) | ((int) a >>> ( s)); a += b; return a; } /* keyBeanUpdate是keyBean的主计算过程inbuf是要变换的字节串inputlen是长度这个 函数由getkeyBeanofStr调用调用之前需要调用keyBeaninit因此把它设计成private的 */ private void keyBeanUpdate(byte[] inbuf int inputLen) { int i index partLen; byte[] block = new byte[]; index = (int)(count[] >>> ) & xF; // /* Update number of bits */ if ((count[] += (inputLen << )) < (inputLen << )) count[]++; count[] += (inputLen >>> ); partLen = index; // Transform as many times as possible if (inputLen >= partLen) { keyBeanMemcpy(buffer inbuf index partLen); keyBeanTransform(buffer); for (i = partLen; i + < inputLen; i += ) { keyBeanMemcpy(block inbuf i ); keyBeanTransform (block); } index = ; } else i = ; ///* Buffer remaining input */ keyBeanMemcpy(buffer inbuf index i inputLen i); } /* keyBeanFinal整理和填写输出结果 */ private void keyBeanFinal () { byte[] bits = new byte[]; int index padLen; ///* Save number of bits */ Encode (bits count ); ///* Pad out to mod index = (int)(count[] >>> ) & xf; padLen = (index < ) ? ( index) : ( index); keyBeanUpdate (PADDING padLen); ///* Append length (before padding) */ keyBeanUpdate(bits ); ///* Store state in digest */ Encode (digest state ); } /* keyBeanMemcpy是一个内部使用的byte数组的块拷贝函数从input的inpos开始把len长度的 字节拷贝到output的outpos位置开始 */ private void keyBeanMemcpy (byte[] output byte[] input int outpos int inpos int len) { int i; for (i = ; i < len; i++) output[outpos + i] = input[inpos + i]; } /* keyBeanTransform是keyBean核心变换程序有keyBeanUpdate调用block是分块的原始字节 */ private void keyBeanTransform (byte block[]) { long a = state[] b = state[] c = state[] d = state[]; long[] x = new long[]; Decode (x block ); /* Round */ a = FF (a b c d x[] S xdaaL); /* */ d = FF (d a b c x[] S xecbL); /* */ c = FF (c d a b x[] S xdbL); /* */ b = FF (b c d a x[] S xcbdceeeL); /* */ a = FF (a b c d x[] S xfcfafL); /* */ d = FF (d a b c x[] S xcaL); /* */ c = FF (c d a b x[] S xaL); /* */ b = FF (b c d a x[] S xfdL); /* */ a = FF (a b c d x[] S xdL); /* */ d = FF (d a b c x[] S xbfafL); /* */ c = FF (c d a b x[] S xffffbbL); /* */ b = FF (b c d a x[] S xcdbeL); /* */ a = FF (a b c d x[] S xbL); /* */ d = FF (d a b c x[] S xfdL); /* */ c = FF (c d a b x[] S xaeL); /* */ b = FF (b c d a x[] S xbL); /* */ /* Round */ a = GG (a b c d x[] S xfeL); /* */ d = GG (d a b c x[] S xcbL); /* */ c = GG (c d a b x[] S xeaL); /* */ b = GG (b c d a x[] S xebcaaL); /* */ a = GG (a b c d x[] S xdfdL); /* */ d = GG (d a b c x[] S xL); /* */ c = GG (c d a b x[] S xdaeL); /* */ b = GG (b c d a x[] S xedfbcL); /* */ a = GG (a b c d x[] S xecdeL); /* */ d = GG (d a b c x[] S xcdL); /* */ c = GG (c d a b x[] S xfddL); /* */ b = GG (b c d a x[] S xaedL); /* */ a = GG (a b c d x[] S xaeeL); /* */ d = GG (d a b c x[] S xfcefafL); /* */ c = GG (c d a b x[] S xfdL); /* */ b = GG (b c d a x[] S xdacaL); /* */ /* Round */ a = HH (a b c d x[] S xfffaL); /* */ d = HH (d a b c x[] S xfL); /* */ c = HH (c d a b x[] S xddL); /* */ b = HH (b c d a x[] S xfdecL); /* */ a = HH (a b c d x[] S xabeeaL); /* */ d = HH (d a b c x[] S xbdecfaL); /* */ c = HH (c d a b x[] S xfbbbL); /* */ b = HH (b c d a x[] S xbebfbcL); /* */ a = HH (a b c d x[] S xbecL); /* */ d = HH (d a b c x[] S xeaafaL); /* */ c = HH (c d a b x[] S xdefL); /* */ b = HH (b c d a x[] S xdL); /* */ a = HH (a b c d x[] S xdddL); /* */ d = HH (d a b c x[] S xedbeL); /* */ c = HH (c d a b x[] S xfacfL); /* */ b = HH (b c d a x[] S xcacL); /* */ /* Round */ a = II (a b c d x[] S xfL); /* */ d = II (d a b c x[] S xaffL); /* */ c = II (c d a b x[] S xabaL); /* */ b = II (b c d a x[] S xfcaL); /* */ a = II (a b c d x[] S xbcL); /* */ d = II (d a b c x[] S xfcccL); /* */ c = II (c d a b x[] S xffeffdL); /* */ b = II (b c d a x[] S xddL); /* */ a = II (a b c d x[] S xfaefL); /* */ d = II (d a b c x[] S xfeceeL); /* */ c = II (c d a b x[] S xaL); /* */ b = II (b c d a x[] S xeaL); /* */ a = II (a b c d x[] S xfeL); /* */ d = II (d a b c x[] S xbdafL); /* */ c = II (c d a b x[] S xaddbbL); /* */ b = II (b c d a x[] S xebdL); /* */ state[] += a; state[] += b; state[] += c; state[] += d; } /*Encode把long数组按顺序拆成byte数组因为java的long类型是bit的 只拆低bit以适应原始C实现的用途 */ private void Encode (byte[] output long[] input int len) { int i j; for (i = j = ; j < len; i++ j += ) { output[j] = (byte)(input[i] & xffL); output[j + ] = (byte)((input[i] >>> ) & xffL); output[j + ] = (byte)((input[i] >>> ) & xffL); output[j + ] = (byte)((input[i] >>> ) & xffL); } } /*Decode把byte数组按顺序合成成long数组因为java的long类型是bit的 只合成低bit高bit清零以适应原始C实现的用途 */ private void Decode (long[] output byte[] input int len) { int i j; for (i = j = ; j < len; i++ j += ) output[i] = biu(input[j]) | (biu(input[j + ]) << ) | (biu(input[j + ]) << ) | (biu(input[j + ]) << );
return; } /* biu是我写的一个把byte按照不考虑正负号的原则的"升位"程序因为java没有unsigned运算 */ public static long biu(byte b) { return b < ? b & xF + : b; } /*byteHEX()用来把一个byte类型的数转换成十六进制的ASCII表示 因为java中的byte的toString无法实现这一点我们又没有C语言中的 sprintf(outbuf"%X"ib) */ public static String byteHEX(byte ib) { char[] Digit = { ABCDEF }; char [] ob = new char[]; ob[] = Digit[(ib >>> ) & XF]; ob[] = Digit[ib & XF]; String s = new String(ob); return s; } /* public static void main(String args[]) { MD m = new MD(); Systemoutprintln("我爱你"+mgetkeyBeanofStr("我爱你")); } */ } |