本例子是参考了一些网站上有关jsp 对 xml 的操作的相关文档,又结合了一些个人的体会。例子涉及的内容是,开发的一个企业内部定餐系统后台管理端的部分代码,功能主要集中在对于餐馆基本信息的管理。
该例子本身开发的起因是我在原公司和同事们一个玩笑的一部分。特此也表达对那些一起共事的朋友们的想念。
例子本身是在tomcat4.01 平台下运行的b/s结构的程式。有关tomcat 的配置,这里不做说明。只讲解一下相关文件及文件夹的目录结构。
目录结构说明:
/tomcat/webapps/canyin/ -----主目录
/tomcat/webapps/canyin/jsp/ -----jsp 文件目录
/tomcat/webapps/canyin/jsp/admin/ -----实现后台管理的jsp 文件的存放目录
/tomcat/webapps/canyin/web-inf/classes/canyin/ ------javabean 文件的存放目录
/tomcat/webapps/canyin/data/ -----xml 文件存放目录
/tomcat/webapps/root/ -----tomcat 启动文件存放文件夹,只存放了index.html 文件
文件简单说明:
/tomcat/webapps/canyin/data/users.xml -----记录用户信息
/tomcat/webapps/canyin/data/restaurants.xml -----记录餐馆的基础信息
/tomcat/webapps/root/index.html -----首页,页面出现输入框,要求用户输入用户名,密码
/tomcat/webapps/canyin/jsp/loginjudge.jsp -----用户身份判断页面,根据用户名称和密码决定页面是转入后台管理端,还是前台客户端。本例子中,用户身份一旦确认为有管理权限,可以进入后台管理端,就直接跳到餐馆基本信息管理页面,简化说明的流程。
/tomcat/webapps/canyin/jsp/admin/admin_rest.jsp -----餐馆基本信息管理页面,管理餐馆的名称,电话,地址等信息
/tomcat/webapps/canyin/web-inf/classes/canyin/checksessionbean.class ----- 后台管理端检测标志用户身份的session 的值,如果不是管理员的话,跳回登陆页面。
/tomcat/webapps/canyin/web-inf/classes/canyin/connxmlbean.class -----连接xml 文件
/tomcat/webapps/canyin/web-inf/classes/canyin/writexmlbean.class -----写入xml文件
文件详细介绍及附带代码说明。
/tomcat/webapps/canyin/data/users.xml
代码:
-
说明:字段含义是用户名,密码以及用户的身份
/tomcat/webapps/canyin/data/restaurants.xml
代码:
-
-
上海亭快餐店
021-76546726
百老汇广场b座
-
香格里拉大饭店
021-2312134
南京路1023号
说明:属性是记录在restaurants.xml 文件中总共有过多少条记录,每新增一条,无论以后删除是否,该值都会增加1,就好象数据库中习惯使用的自动增加1的id 项。用来给新增的 的属性赋一个唯一的值。其它的字段意思比较明显。
/tomcat/webapps/root/index.html (单纯的html代码)
代码:
oddworld 餐饮系统
餐饮系统登录
餐饮系统登录
登录名:
name=username class=stedit value=joard>
密码:
name=userpass type=password value=oddworld>
说明:把用户名称和用户密码提交到/tomcat/webapps/canyin/jsp/loginjudge.jsp
/tomcat/webapps/canyin/web-inf/classes/canyin/checksessionbean.class (代码是相应的java 文件)
package canyin;
import javax.servlet.http.httpsession;
import javax.servlet.http.httpservletrequest;
public class checksessionbean {
private boolean bolcheckpass=false;
private httpservletrequest request = null;
public boolean checksessionbean(httpservletrequest request,string strsessionname,string strcheckvalue){
public boolean checksessionbean(httpservletrequest request){
httpsession session = request.getsession(false);
return(bolcheckpass);
if (strsessionname==null || strcheckvalue==null){
return(bolcheckpass);
}else{
if (session!=null && session.getvalue(strsessionname)!=null){
bolcheckpass=session.getvalue(strsessionname).equals(strcheckvalue);
}
return(bolcheckpass);
}
}
}
说明:检验参数传入的session 名称的数值和参数传入的字段的数值是否相等。
/tomcat/webapps/canyin/web-inf/classes/canyin/connxmlbean.class
代码:
package canyin;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.domsource;
import javax.xml.transform.stream.streamresult;
import org.w3c.dom.*;
public class connxmlbean {
private documentbuilderfactory factory=null;
private documentbuilder builder=null;
private document doc=null;
public connxmlbean(){}
public string connxml(string xmlfilename){
string strexc=;
try{
factory = documentbuilderfactory.newinstance();
builder=factory.newdocumentbuilder();
doc=builder.parse(xmlfilename);
doc.normalize();
}catch(exception e){
strexc=e.tostring();
}
return(strexc);
}
public document getxmldoc(){
return(doc);
}
}
说明:打开一个指定xml 文件
/tomcat/webapps/canyin/web-inf/classes/canyin/writexmlbean.class
代码:
package canyin;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.domsource;
import javax.xml.transform.stream.streamresult;
import java.io.file;
import org.w3c.dom.*;
public class writexmlbean {
public writexmlbean(){}
public string writexml(document doc,string xmlfilename){
string strexc=;
try{
transformerfactory tfactory = transformerfactory.newinstance();
transformer transformer = tfactory.newtransformer();
domsource source = new domsource(doc);
streamresult result = new streamresult(new file(xmlfilename));
transformer.transform(source,result);
}catch(exception e){
strexc=e.tostring();
}
return(strexc);
}
}
说明:写入dom 的内容到一个指定的xml 文件。
/tomcat/webapps/canyin/jsp/loginjudge.jsp
代码:
copy right by joard ast
loginjudge.jsp 功能:用户身份校验,根据 /data/user.xml 文件内标示的用户不同的身份
决定转入后台管理页面,还是客户点菜页面。
--%>
session.setmaxinactiveinterval(1800);
document doc;
nodelist users;
string strexc=;
string strusername,strpassword;
strusername=(string)request.getparameter(username);
strpassword=(string)request.getparameter(userpass);
//校验数据是否为空
if (strusername== || strpassword== ){
out.println();
return;
}
xmlbean.connxml(webapps/canyin/data/users.xml);
doc=xmlbean.getxmldoc();
try{
users =doc.getelementsbytagname(user);
for (int i=0;i element user=(element) users.item(i);
string stratrnamevalue=user.getattributenode(name).getnodevalue();
string stratrpasswordvalue=user.getattributenode(password).getnodevalue();
string stratrrolevalue=user.getattributenode(roles).getnodevalue();
if (stratrnamevalue.equals(strusername) && stratrpasswordvalue.equals(strpassword)){
if (stratrrolevalue.equals(admin)){
out.println();
//设置标示用户身份的 session(sesuserrole) ,管理员身份为 admin
session.setattribute(sesuserrole,admin);
//跳转到管理页面
response.sendredirect(admin/admin_rest.jsp);
return;
}else{
//设置标示用户身份的 session(sesuserrole) ,管理员身份为 user
session.setattribute(sesuserrole,user);
//跳转到普通用户页面
response.sendredirect(index.jsp);
return;
}
}else{
out.println();
return;
}
}
}catch(exception e){
strexc=e.tostring();
}
%>
说明:.......
/tomcat/webapps/canyin/jsp/admin/admin_rest.jsp
代码:
copy right by joard ast
admin_rest.jsp 功能:后台管理页面,餐馆管理页面。
--%>
if(!checksessionbean.checksessionbean(request,sesuserrole,admin)){
out.print(showdialog(您没有管理的权限!,/index.html));
return;
}
//从餐馆资料文件 rest.xml 中得到相关数据
document doc;
nodelist restaurants;
string stract;
int intid=0;
string stroperation=show;
//接受外部传入的参数
stract=(string)request.getparameter(act);
xmlbean.connxml(webapps/canyin/data/restaurants.xml);
doc=xmlbean.getxmldoc();
restaurants =doc.getelementsbytagname(restaurant);
//根据外部传入的参数来决定对 restaurant.xml 文件的操作
if (stract!=null){
if(stract.equals(addnewdo)){
string strname;
string strphone;
string straddress;
text textseg;
strname=(string)request.getparameter(name).trim();
strphone=(string)request.getparameter(phone).trim();
straddress=(string)request.getparameter(address).trim();
//数据校验
if(strname==null){
out.print(showdialog(餐馆名称不能为空!));
return;
}
if(strphone==null){
out.print(showdialog(餐馆电话不能为空!));
return;
}
/*if(straddress==null){
out.print(showdialog(餐馆地址不能为空!));
return;
}*/
//校验数据的唯一性
for(int i=0;i element restaurant=(element) restaurants.item(i);
if(((string)restaurant.getelementsbytagname(name).item(0).getfirstchild().getnodevalue()).equals(strname)){
out.print(showdialog(餐馆名称重复!));
return;
}else{
if(((string)restaurant.getelementsbytagname(name).item(0).getfirstchild().getnodevalue()).equals(strphone)){
out.print(showdialog(餐馆电话重复!));
return;
}
}
}
//得到已有的记录数,给新增的餐馆记录设定唯一的递增的id 属性
int intnum=0;
element restnum=(element)doc.getelementsbytagname(restaurants).item(0);
intnum=integer.parseint(restnum.getattributenode(num).getnodevalue());
intnum+=1;
//为restaurants的属性num 的数值加1
restnum.getattributenode(num).setnodevalue(string.valueof(intnum));
//新增节点
element newrestaurant=doc.createelement(restaurant);
attr newarrid=doc.createattribute(id);
//attribute newarrid = new attribute(id,string.valueof(intnum));
textseg=doc.createtextnode(string.valueof(intnum));
newarrid.setvalue(string.valueof(intnum));
newrestaurant.setattributenode(newarrid);
element newname=doc.createelement(name);
textseg=doc.createtextnode(strname);
newname.appendchild(textseg);
newrestaurant.appendchild(newname);
element newphone=doc.createelement(phone);
textseg=doc.createtextnode(strphone);
newphone.appendchild(textseg);
newrestaurant.appendchild(newphone);
element newaddress=doc.createelement(address);
textseg=doc.createtextnode(straddress);
newaddress.appendchild(textseg);
newrestaurant.appendchild(newaddress);
doc.getdocumentelement().appendchild(newrestaurant);
//调用bean 写入相应的xml文件
writexmlbean.writexml(doc,webapps/canyin/data/restaurants.xml);
response.sendredirect(request.getrequesturi());
return;
}
if(stract.equals(modido)){
string strname;
string strphone;
string straddress;
text textseg;
int modiid;
//记录要修改的记录是item(i)的哪一项
int inti=0;
strname=(string)request.getparameter(name).trim();
strphone=(string)request.getparameter(phone).trim();
straddress=(string)request.getparameter(address).trim();
modiid=integer.parseint(request.getparameter(recordid).trim());
//数据校验
if(strname==null){
out.print(showdialog(餐馆名称不能为空!));
return;
}
if(strphone==null){
out.print(showdialog(餐馆电话不能为空!));
return;
}
if(modiid==0){
out.print(showdialog(你要修改餐馆的记录不存在!));
return;
}
/*if(straddress==null){
out.print(showdialog(餐馆地址不能为空!));
return;
}*/
//标志显示记录存在
boolean recordexist=false;
//校验数据的唯一性
for(int i=0;i element restaurant=(element) restaurants.item(i);
if(integer.parseint(restaurant.getattributenode(id).getnodevalue())==modiid){
recordexist=true;
inti=i;
}
if(((string)restaurant.getelementsbytagname(name).item(0).getfirstchild().getnodevalue()).equals(strname) && integer.parseint(restaurant.getattributenode(id).getnodevalue())!=modiid ){
out.print(showdialog(餐馆名称重复!));
return;
}else{
if(((string)restaurant.getelementsbytagname(name).item(0).getfirstchild().getnodevalue()).equals(strphone) && integer.parseint(restaurant.getattributenode(id).getnodevalue())!=modiid ){
out.print(showdialog(餐馆电话重复!));
return;
}
}
}
if(!recordexist){
out.print(showdialog(你要修改餐馆的记录不存在!));
return;
}else{
//进行记录更改的操作
try{
element modirestaurant=(element) restaurants.item(inti);
modirestaurant.getelementsbytagname(name).item(0).getfirstchild().setnodevalue(strname);
modirestaurant.getelementsbytagname(phone).item(0).getfirstchild().setnodevalue(strphone);
modirestaurant.getelementsbytagname(address).item(0).getfirstchild().setnodevalue(straddress);
//调用bean 写入相应的xml文件
writexmlbean.writexml(doc,webapps/canyin/data/restaurants.xml);
response.sendredirect(request.getrequesturi());
return;
}catch(exception e){}
}
}
//进行删除操作
if(stract.equals(del)){
int delid;
//记录要修改的记录是item(i)的哪一项
int inti=0;
delid=integer.parseint(request.getparameter(recordid).trim());
if(delid==0){
out.print(showdialog(你要修改餐馆的记录不存在!));
return;
}
file://标志显示记录存在
boolean recordexist=false;
//校验数据的唯一性
for(int i=0;i element restaurant=(element) restaurants.item(i);
if(integer.parseint(restaurant.getattributenode(id).getnodevalue())==delid){
recordexist=true;
inti=i;
}
}
if(!recordexist){
out.print(showdialog(你要删除餐馆的记录不存在!));
return;
}else{
//进行记录删除的操作
try{
node delnode=(node)restaurants.item(inti);
doc.getelementsbytagname(restaurants).item(0).removechild(delnode);
//调用bean 写入相应的xml文件
writexmlbean.writexml(doc,webapps/canyin/data/restaurants.xml);
response.sendredirect(request.getrequesturi());
return;
}catch(exception e){}
}
}
}
//由外部传入参数决定页面相应的处理状态
if (stract==null){
stroperation=show;
}else{
if (stract.equals(modi)){
stroperation=modi;
intid=integer.parseint(request.getparameter(recordid));
}else{
if(stract.equals(addnew)){
stroperation=addnew;
}else{
stroperation=show;
}
}
}
//如果为空记录,则变更页面状态为“新增”
if (restaurants.getlength()==0){
stroperation=addnew;
}
%>
oddworld 餐饮系统
餐饮系统管理--餐馆管理
[ 退出系统 ]
width=90%>
餐馆名称
餐馆电话
餐馆地址
修改
删除
for(int i=0;i {
element restaurant=(element) restaurants.item(i);
if (stroperation==modi && integer.parseint(restaurant.getattributenode(id).getnodevalue())==intid){
%>
?act=modido method=post onsubmit=''return checkform(this);'' >
>
style=max-width:90% value= out.print(restaurant.getelementsbytagname(name).item(0).getfirstchild().getnodevalue());
}%>
maxlength=40 >
style=height: 22px; width: 100px value= out.print(restaurant.getelementsbytagname(phone).item(0).getfirstchild().getnodevalue());
}%> maxlength=20 >
style=height: 22px; width: 200px value=
if(restaurant.getelementsbytagname(address).item(0).haschildnodes()){
out.print(restaurant.getelementsbytagname(address).item(0).getfirstchild().getnodevalue());
}%> maxlength=100 >
height=15 src=../../images/editok.gif width=15>
//显示正常的格式 %>
out.print(restaurant.getelementsbytagname(name).item(0).getfirstchild().getnodevalue());
}%>
out.print(restaurant.getelementsbytagname(phone).item(0).getfirstchild().getnodevalue());
}%>
if(restaurant.getelementsbytagname(address).item(0).haschildnodes()){
out.print(restaurant.getelementsbytagname(address).item(0).getfirstchild().getnodevalue());
}%>
?act=modi&recordid=> height=15 src=../../images/edit.gif width=15>
height=15
onclick=javascript:if(confirm(''您是否确定删除本记录,删除后将导至记录无法使用?'')){window.location.href=''?act=del&recordid='';}
src=../../images/delete.gif style=max-width:90% width=15>
}%>
//显示新增的格式%>
?act=addnewdo method=post onsubmit=''return checkform2(this);'' >
style=height: 22px; width: 150px value= maxlength=40 >
style=height: 22px; width: 100px value= maxlength=20 >
style=height: 22px; width: 200px value= maxlength=100 >
height=15 src=../../images/editok.gif width=15>
%>
if(stroperation==modi){
%>
}else{
%>
?act=addnew'';> }
} %>
说明:本文件的书写有很多地方并不简练,因为在程式的开发过程中,过分简练的程序往往会带来后期维护的困难。
开发心得:
doc.getelementsbytagname(restaurants).item(int i)的返回值是node 型,如果不是要调用它的属性值,没有必要强制转型为 element型。可以直接操作。本系统因为开发的参考资料的错误,所以全都采用了强制转型。可以在以后的开发中考虑使用node 直接进行操作。
trim() 和 interger.parseint() 函数都不可以接受null 型的数值
在tomcat 下左右的文件都是目录从tomcat 算起,具体情况请参见\webapps\canyin\jsp\userjudge.jsp 里关于xml 路径的写法。
对原代码感兴趣的朋友请通过如下信箱和我联系,joard@163.com