??xml version="1.0" encoding="utf-8" standalone="yes"?>
|
+-- build/ <-- WAR/EAR档的目录
+-- classes/ <-- ~译的输出目录,与JBuilder兼容
+-- src/ <-- Java源文件目?br />
+-- web/ <-- WEB Content 目录
| |
| +--pages/ <-- JSP 文g目录
| +--WEB-INF/ <-- web.xml {配|文?br />
+-- ejb <-- EJB Content 目录
| |
| +---INF/ <-- EJB 配置文g
+-- ear <-- EAR Content 目录
| |
| +---INF/ <-- EAR 配置文g
|-- lib <-- 目所要用到的library
接下来第一步,是要先定义好一些全局的参敎ͼ以便以后更改h方便Q风?br /> 大家自己选择好了Q我用的是如下的方式Q?/span>
(1) l出目的目录:
<!--// project directories //--><property name="dir.project"
="D:/Code/MyProject"/><property name="dir.project.lib"
="${dir.project}/lib"/><property name="dir.project.src"
="${dir.project}/src"/><property name="dir.project.web_module"
="${dir.project}/web"/><property name="dir.project.ejb_module"
="${dir.project}/ejb"/><property name="dir.project.ear_module"
="${dir.project}/ear"/><!--// compile, build and deploy
directories //--><property name="dir.project.compile"
="${dir.project}/classes"/><property
name="dir.project.compile.jspcache"
="${dir.project.compile}/jspcache"/><property
name="dir.project.build" ="${dir.project}/build"/><!--// J2EE
Container //--><property name="dir.appserver.tomcat.home"
="D:/J2EE_HOME/AppServer/Tomcat"/><property
name="dir.appserver.oc4j.j2ee.home"
="D:/J2EE_HOME/AppServer/OC4J/j2ee/home"/>
(2) 定义Java Source的编译选项
<!--//
Java compiler options //--> <property name="opt.compile.source"
="1.4"/><property name="opt.compile.target"
="1.4"/><property name="opt.compile.encoding"
="UTF-8"/><property name="opt.compile.deprecation"
="on"/><property name="opt.compile.debug" ="on"/><property
name="opt.compile.optimize" ="off"/>
(3) 如果需?import EJB library 的话Q给Z面的定义Q后面会用到
<!--// EJB imported resource //--><property name="import.ejb.report.server" ="${dir.project.lib}/Appwork.jar"/>
(4) l出部vWAR/EAR文g的名Uͼ
<!--// Deployment //--><property name="deploy.file.ejb_module"
="MyApp_EJB.jar" /><property name="deploy.file.web_module"
="MyApp_WEB.war" /><property name="deploy.file.ear_module"
="MyApp.ear" />
(5) l出CLASSPATH的定义,引入相关的Library和项目编译生成的Java Classes
<path id="CLASSPATH"><!--// Tomcat Libraries
//--><fileset dir="${dir.appserver.tomcat.home}/bin">
<include name="*.jar"/></fileset> <fileset
dir="${dir.appserver.tomcat.home}/server/lib"> <include
name="*.jar"/> </fileset> <fileset
dir="${dir.appserver.tomcat.home}/common/lib"> <include
name="*.jar"/> </fileset> <!--// Depended Libraries
//--><pathelement
location="${dir.project.lib}/abc.jar"/><pathelement
location="${dir.project.lib}/AppServer.jar"/><pathelement
location="${dir.project.lib}/AppServiceClient.jar"/><pathelement
location="${dir.project.lib}/AppUtil.jar"/><pathelement
location="${dir.project.lib}/xport.jar"/><pathelement
location="${dir.project.lib}/jaxen-full.jar"/><pathelement
location="${dir.project.lib}/jstl.jar"/><pathelement
location="${dir.project.lib}/log4j-1.2.13.jar"/><pathelement
location="${dir.project.lib}/ojdbc14.jar"/><pathelement
location="${dir.project.lib}/saxpath.jar"/><pathelement
location="${dir.project.lib}/standard.jar"/><pathelement
location="${dir.project.lib}/taglibs-log.jar"/><!--// Project
classes //--><pathelement
location="${dir.project.compile}"/></path>
(6) 基本的clean和init的task
<target name="clean"><delete
dir="${dir.project.build}"/><delete
dir="${dir.project.compile.jspcache}"/><delete
dir="${dir.project.compile}"/><delete
dir="${dir.project.web_module}/WEB-INF/classes"/><delete
dir="${dir.project.web_module}/WEB-INF/lib"/></target><target
name="init"><mkdir dir="${dir.project.compile}"/><mkdir
dir="${dir.project.compile.jspcache}"/><mkdir
dir="${dir.project.web_module}/WEB-INF/classes"/><mkdir
dir="${dir.project.web_module}/WEB-INF/lib"/><mkdir
dir="${dir.project.build}"/></target>
(7) ~译Java Source
<target
name="src_compile" depends="init"><!--// compile the Java source
//--><javac srcdir="${dir.project.src}"
destdir="${dir.project.compile}" encoding="${opt.compile.encoding}"
source="${opt.compile.source}" target="${opt.compile.source}"
deprecation="${opt.compile.deprecation}"debug="${opt.compile.debug}"
optimize="{opt.compile.optimize}" ><classpath
refid="CLASSPATH"/><include
name="**/*.java"/></javac><!--// copy the classpath
resources //--><copy
todir="${dir.project.compile}"><fileset
dir="${dir.project.src}"><exclude
name="**/*.java"/></fileset></copy> </target>
(8) 预编译JSP文gQ可选择ZTomcat或是Oracle Application Server
<!--// for Tomcat //--> <target name="jsp_src_generate"
depends="src_compile"><taskdef classname="org.apache.jasper.JspC"
name="jasper2"><classpath refid="CLASSPATH"/>
</taskdef><jasper2 validateXml="false"
verbose="9"uriroot="${dir.project.web_module}"
outputDir="${dir.project.compile.jspcache}"
webXmlFragment="${dir.project.compile.jspcache}/generated-web.xml"
/> </target><target name="jsp_src_compile"><javac
srcdir="${dir.project.compile.jspcache}"
destdir="${dir.project.compile.jspcache}"
encoding="${opt.compile.encoding}" source="${opt.compile.source}"
target="${opt.compile.source}"
deprecation="${opt.compile.deprecation}"debug="${opt.compile.debug}"
optimize="{opt.compile.optimize}" ><classpath
refid="CLASSPATH"/><include
name="**"/></javac></target><target
name="jsp_precompile" depends="src_compile, jsp_src_generate,
jsp_src_compile" />
<property name="app.name" ="demo"/>
<property name="app.dir" location="../WebRoot"/>
<property name="webserver.home" location="../../../platform/jakarta-tomcat-5.0.19"/>
<property name="webserver.deploy" location="${webserver.home}/webapps/"/>
<property name="src.dir" location="../src"/>
<property name="build.dir" location="${app.dir}/WEB-INF/classes"/>
<property name="lib.dir" location="${app.dir}/WEB-INF/lib"/>
<property name="dist.dir" location="../dist"/>
<property name="properties.dir" location="${src.dir}/com/easydone/struts/ApplicationResources.properties"/>
<property name="properties_zh.dir" location="${build.dir}/com/easydone/struts/ApplicationResources_zh.properties"/>
<property name="doc.dir" ="../api"/>
<property name="packages" ="com.easydone.*"/>
<echo>+--------------------------------------------------+</echo>
<echo>| |</echo>
<echo>| R U N N I N G A N T REPOSITORY |</echo>
<echo>| |</echo>
<echo>+--------------------------------------------------+</echo>
<!---Help Information-->
<target name="usage" >
<echo message=""/>
<echo message="-------------------------------------------------------------"/>
<echo message="操作说明Q?/>
<echo message="首先您~写的java文g拯?{src.dir}目录?按先后顺序执行以下命令既可?/>
<echo message="W一步:compile 命o~译*.java"/>
<echo message="W二步:deploy 命o生成${app.name}.jar文g"/>
<echo message="W三步:doc 命o生成详细javadoc文档"/>
<echo message="每一步操作都能看?BUILD SUCCESSFUL提示后,表示您操作成功!"/>
<echo message="-------------------------------------------------------------"/>
<echo message=""/>
</target>
<!-- =================================================================== -->
<!-- 讄应用环境变量 -->
<!-- =================================================================== -->
<path id="compile.classpath">
<pathelement path ="${build.dir}"/>
<fileset dir="${lib.dir}">
<include name="**/*.jar"/>
</fileset>
</path>
<!-- =================================================================== -->
<!-- 格式化中文资源包Q解军_际化中文问题 -->
<!-- =================================================================== -->
<target name="checkToZh">
<uptodate property="toZh.notRequired"
srcfile="${properties.dir}"
targetfile="${properties_zh.dir}"/>
</target>
<target name="toZh" depends="checkToZh" unless="toZh.notRequired">
<delete file="${properties_zh.dir}"/>
<!-- native2ascii struts.properties -->
<exec executable="native2ascii">
<arg line=" ${properties.dir} ${properties_zh.dir}"/>
</exec>
<echo message="toZh performed!"/>
</target>
<!-- =================================================================== -->
<!-- 初始化创建相兛_用目?nbsp; -->
<!-- =================================================================== -->
<target name="prepare" deion="create build,dist files">
<mkdir dir="${build.dir}"/>
<mkdir dir="${dist.dir}"/>
</target>
<!-- =================================================================== -->
<!-- 初始化应用程序,删除相关目录 -->
<!-- =================================================================== -->
<target name="clean" deion="Delete build files">
<delete dir="${build.dir}"/>
<delete dir="${dist.dir}"/>
</target>
<!-- =================================================================== -->
<!-- compile 命oQ执行javac~译命o -->
<!-- =================================================================== -->
<target name="compile" depends="prepare">
<javac srcdir="${src.dir}" destdir="${build.dir}" debug="on">
<classpath refid="compile.classpath"/>
</javac>
</target>
<!-- =================================================================== -->
<!-- update命oQ编译及处理国际化中文资源文? -->
<!-- =================================================================== -->
<target name="update" depends="compile,toZh">
<!--copy classes-->
<copy todir="${webserver.deploy}/${app.name}/WEB-INF/classes" includeEmptyDirs="no">
<fileset dir="${build.dir}"/>
</copy>
<!--copy pages-->
<copy todir="${webserver.deploy}/${app.name}" includeEmptyDirs="no">
<fileset dir="${app.dir}"/>
</copy>
<!-- copy libs-->
<copy todir="${webserver.deploy}/${app.name}/WEB-INF/lib" includeEmptyDirs="no">
<fileset dir="${lib.dir}"/>
</copy>
</target>
<!-- =================================================================== -->
<!-- 部v应用E序Q依赖于 compile命oclean,prepare,compile,dist -->
<!-- =================================================================== -->
// 初始化可以拖拽的Element的函敎ͼ与拖拽无关的我去掉了
draggable(el) {
// 公用的开始拖拽的函数
this ._dragStart = start_Drag;
// 公用的正在拖拽的函数
this ._drag = when_Drag;
// 公用的拖拽结束的函数
this ._dragEnd = end_Drag;
// q个函数主要用来q行拖拽l束后的dom处理
this ._afterDrag = after_Drag;
// 是否正在被拖动,一开始当然没有被拖动
this .isDragging = false ;
// 这个Element的this指针注册在elmq个变量里面Q方便在自己的上下文以外调用自己的函数等Q很常用的方?
this .elm = el;
// 触发拖拽的ElementQ在q里是q个div上显C标题的那个div
this .header = getElementById(el.id + " _h " );
// 对于有i的element拖拽不同Q这里检一下ƈ记录
this .hasI = this .elm.getElementsByTagName( " I " ).length > 0 ;
// 如果扑ֈ了headerq定drag相关的event
if ( this .header) {
// 拖拽时的叉子鼠标指针
this .header.style.cursor = " move " ;
// 函数绑定到header和element的this上,参照那个函数的说?
Drag.init( this .header, this .elm);
// 下面三个语句写好的三个函数l定l这个elemnt的三个函数钩子上Q也实Celement从draggablel承可拖拽的函数
this .elm.onDragStart = Util.bind( this , " _dragStart " );
this .elm.onDrag = Util.bind( this , " _drag " );
this .elm.onDragEnd = Util.bind( this , " _dragEnd " );
}
};
// 可拖拽Element的原形,用来eventl定到各个钩子,q部分市比较通用的,netvibes也是基本完全相同的实?
// q部分推荐看dindin的这个,也会帮助理解Q?a >http://www.jroller.com/page/dindin/?anchor=pro_java_12
var Drag = {
// 对这个element的引用,一ơ只能拖拽一个Element
obj: null ,
// element是被拖拽的对象的引用QelementHeader是鼠标可以拖拽的区?
init: (elementHeader, element) {
// startl定到down事gQ按下鼠标触发start
elementHeader.down = Drag.start;
// element存到header的obj里面Q方便header拖拽的时候引?
elementHeader.obj = element;
// 初始化绝对的坐标Q因Z是position=absolute所以不会v什么作用,但是防止后面onDrag的时候parse出错?
if (isNaN(parseInt(element.style.left))) {
element.style.left = " 0px " ;
}
if (isNaN(parseInt(element.style.top))) {
element.style.top = " 0px " ;
}
// 挂上I,初始化这几个成员Q在Drag.init被调用后才帮定到实际的函敎ͼ可以参照draggable里面的内?
element.onDragStart = new ();
element.onDragEnd = new ();
element.onDrag = new ();
},
// 开始拖拽的l定Q绑定到鼠标的移动的event?
start: (event) {
var element = Drag.obj = this .obj;
// 解决不同览器的event模型不同的问?
event = Drag.fixE(event);
// 看看是不是左键点?
if (event.which != 1 ) {
// 除了左键都不起作?
return true ;
}
// 参照q个函数的解释,挂上开始拖拽的钩子
element.onDragStart();
// 记录鼠标坐标
element.lastMouseX = event.clientX;
element.lastMouseY = event.clientY;
// Global的eventl定到被拖动的element上面?
up = Drag.end;
move = Drag.drag;
return false ;
},
// Element正在被拖动的函数
drag: (event) {
// 解决不同览器的event模型不同的问?
event = Drag.fixE(event);
// 看看是不是左键点?
if (event.which == 0 ) {
// 除了左键都不起作?
return Drag.end();
}
// 正在被拖动的Element
var element = Drag.obj;
// 鼠标坐标
var _clientX = event.clientY;
var _clientY = event.clientX;
// 如果鼠标没动׃么都不作
if (element.lastMouseX == _clientY && element.lastMouseY == _clientX) {
return false ;
}
// 刚才Element的坐?
var _lastX = parseInt(element.style.top);
var _lastY = parseInt(element.style.left);
// 新的坐标
var newX, newY;
// 计算新的坐标Q原先的坐标+鼠标Ud的值差
newX = _lastY + _clientY - element.lastMouseX;
newY = _lastX + _clientX - element.lastMouseY;
// 修改element的显C坐?
element.style.left = newX + " px " ;
element.style.top = newY + " px " ;
// 记录element现在的坐标供下一ơ移动?
element.lastMouseX = _clientY;
element.lastMouseY = _clientX;
// 参照q个函数的解释,挂接上Drag时的钩子
element.onDrag(newX, newY);
return false ;
},
// Element正在被释攄函数Q停止拖?
end: (event) {
// 解决不同览器的event模型不同的问?
event = Drag.fixE(event);
// 解除对Global的event的绑?
move = null ;
up = null ;
// 先记录下onDragEnd的钩子,好移除obj
var _onDragEndFuc = Drag.obj.onDragEnd();
// 拖拽完毕Qobj清空
Drag.obj = null ;
return _onDragEndFuc;
},
// 解决不同览器的event模型不同的问?
fixE: (ig_) {
if ( typeof ig_ == " undefined " ) {
ig_ = event;
}
if ( typeof ig_.layerX == " undefined " ) {
ig_.layerX = ig_.offsetX;
}
if ( typeof ig_.layerY == " undefined " ) {
ig_.layerY = ig_.offsetY;
}
if ( typeof ig_.which == " undefined " ) {
ig_.which = ig_.button;
}
return ig_;
}
};
// 下面是初始化的函CQ看看上面这些东西怎么被调?
var _IG_initDrag = (el) {
// column那个容器Q在google里面是那个table布局的tbodyQnetvibes用的<div>
Util.rootElement = el;
// q个tbody的行
Util._rows = Util.rootElement.tBodies[ 0 ].rows[ 0 ];
// 列,google?列,其实也可以更?
Util.column = Util._rows.cells;
// 用来存取可拖拽的对象
Util.dragArray = new Array();
var counter = 0 ;
for ( var i = 0 ; i < Util.column.length; i ++ ) {
// 搜烦所有的column
var ele = Util.column[i];
for ( var j = 0 ; j < ele.childNodes.length; j ++ ) {
// 搜烦每一column里面的所有element
var ele1 = ele.childNodes[j];
// 如果是div把它初始化Z个draggable对象
if (ele1.tagName == " DIV " ) {
Util.dragArray[counter] = new draggable(ele1);
counter ++ ;
}
}
}
};
// google的页面里可以拖动的部分的id?t_1"
// 挂蝲刎ͼ载入完毕执行。不q实际上google没有用?
// 而是写在面最下面Q异曲同工吧Q也许直接写在页面是U怪癖Q或者也有可能是兼容性考虑?
// 请将下面两条被注释掉的代码加Q到你自׃载的一个google ig面里面Q把里面的所有其余删除,挂上q个js也可以拖拽了Q哈?
// _table=getElementById("t_1");
// = _IG_initDrag(_table);
使搜索引搜烦蜘蛛的收录由被动变ؓdQ?span style="font-family: Times New Roman;">google Sitemap服务目前不提供在线创徏Sitemap的功能,但是我们可以借助W三方网站提供的此类服务Q打开|站Q?a >http://www.xml-sitemaps.comQ(如图1Q?nbsp;
?#8220;Starting URL”栏中输入你自q|站地址Q在“Change frequency”下拉列表选择|站的更新频率(l常 每天 每年{不同的时段Q,?#8220;Last modification”选择最后修Ҏ_选择Use server's response服务器反映时?nbsp;Q,?#8220;Priority”栏中速入跟新的优先权Q最后点?#8220;Start”按钮创徏|站地图 Q如?Q?img src="http://www.6b9g.com/sitemap0.gif" onclick="javascript:window.open(this.src);" style="cursor: pointer;" onload="rsimg(this,500)" alt="" />
完成操作后,我们在昄的结果中看到各式各样的网站生成地图Sitemap文gQ将“Sitemap.xml”下蝲到本地然后再传到服务器主目录下,下面用Gmail帐户登陆到google Sitemap,d自己的网站sitemap文gQ如?Q?img src="http://www.6b9g.com/sitemap.gif" onclick="javascript:window.open(this.src);" style="cursor: pointer;" onload="rsimg(this,500)" alt="" />Q再选在d该站点的sitemapQ注意在选择分类的时候选择d常规|络(如图3)sitemap然后输入刚才上传得那个sitemap.xml地址Q各?a >http://www.6b9g.com/sitemap.xml 再点?#8220;d普通sitemap” 按钮
首发 高峰 站长互动信息|?nbsp; http://www.6b9g.com
Introducing FileUpload
The FileUpload component has the
capability of simplifying the handling of files uploaded to a server.
Note that the FileUpload component is meant for use on the server side;
in other words, it handles where the files are being uploaded to—not
the client side where the files are uploaded from. Uploading files from
an HTML form is pretty simple; however, handling these files when they
get to the server is not that simple. If you want to apply any rules
and store these files based on those rules, things get more difficult.
The FileUpload component remedies this situation, and in very few lines of code you can easily manage the files uploaded and store them in appropriate locations. You will now see an example where you upload some files first using a standard HTML form and then using HttpClient code.
Using HTML File Upload
The commonly used methodology to upload
files is to have an HTML form where you define the files you want to
upload. A common example of this HTML interface is the Web page you
encounter when you want to attach files to an email while using any of
the popular Web mail services.
In this example, you will create a simple HTML page where you provide for three files to be uploaded. Listing 1-1 shows the HTML for this page. Note that the enctype attribute for the form has the multipart/form-data, and the input tag used is of type file. Based on the of the action attribute, on form submission, the data is sent to ProcessFileUpload.jsp.
Listing 1-1. UploadFiles.html
<HTML>
<HEAD>
< HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252"/>
<TITLE>File Upload Page</TITLE>
</HEAD>
<BODY>Upload Files
<FORM name="filesForm" action="ProcessFileUpload.jsp"
method="post" enctype="multipart/form-data">
File 1:<input type="file" name="file1"/><br/>
File 2:<input type="file" name="file2"/><br/>
File 3:<input type="file" name="file3"/><br/>
<input type="submit" name="Submit" ="Upload Files"/>
</FORM>
</BODY>
</HTML>
You can use a servlet to handle the file upload. I have used JSP to minimize the code you need to write. The task that the JSP has to accomplish is to pick up the files that are sent as part of the request and store these files on the server. In the JSP, instead of displaying the result of the upload in the Web browser, I have chosen to print messages on the server console so that you can use this same JSP when it is not invoked through an HTML form but by using HttpClient-based code.
Listing 1-2 shows the JSP code. Note the code that checks whether the item is a form field. This check is required because the Submit button contents are also sent as part of the request, and you want to distinguish between this data and the files that are part of the request. You have set the maximum file size to 1,000,000 bytes using the setSizeMax method.
Listing 1-2. ProcessFileUpload.jsp
<%@ page contentType="text/html;charset=windows-1252"%>
<%@ page import="org.apache.commons.fileupload.DiskFileUpload"%>
<%@ page import="org.apache.commons.fileupload.FileItem"%>
<%@ page import="jsp servlet ejb .util.List"%>
<%@ page import="jsp servlet ejb .util.Iterator"%>
<%@ page import="jsp servlet ejb .io.File"%>
html>
<head>
< http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>Process File Upload</title>
</head>
<%
System.out.println("Content Type ="+request.getContentType());
DiskFileUpload fu = new DiskFileUpload();
// If file size exceeds, a FileUploadException will be thrown
fu.setSizeMax(1000000);
List fileItems = fu.parseRequest(request);
Iterator itr = fileItems.iterator();
while(itr.hasNext()) {
FileItem fi = (FileItem)itr.next();
//Check if not form field so as to only handle the file inputs
//else condition handles the submit button input
if(!fi.isFormField()) {
System.out.println(""nNAME: "+fi.getName());
System.out.println("SIZE: "+fi.getSize());
//System.out.println(fi.getOutputStream().toString());
File fNew= new File(application.getRealPath("/"), fi.getName());
System.out.println(fNew.getAbsolutePath());
fi.write(fNew);
}
else {
System.out.println("Field ="+fi.getFieldName());
}
}
%>
<body>
Upload Successful!!
</body>
</html>
CAUTION With FileUpload 1.0 I found that when the form was submitted using Opera version 7.11, the getName method of the class FileItem returns just the name of the file. However, if the form is submitted using Internet Explorer 5.5, the filename along with its entire path is returned by the same method. This can cause some problems.
To run this example, you can use any three files, as the contents of the files are not important. Upon submitting the form using Opera and uploading three random XML files, the output I got on the Tomcat server console was as follows:
Content Type =multipart/form-data; boundary=----------rz7ZNYDVpN1To8L73sZ6OE
NAME: academy.xml
SIZE: 951
D:"javaGizmos"jakarta-tomcat-4.0.1"webapps"HttpServerSideApp"academy.xml
NAME: academyRules.xml
SIZE: 1211
D:"javaGizmos"jakarta-tomcat-4.0.1"webapps"HttpServerSideApp"academyRules.xml
NAME: students.xml
SIZE: 279
D:"javaGizmos"jakarta-tomcat-4.0.1"webapps"HttpServerSideApp"students.xml
Field =Submit
However, when submitting this same form using Internet Explorer 5.5, the output on the server console was as follows:
Content Type =multipart/form-data; boundary=---------------------------7d3bb1de0
2e4
NAME: D:"temp"academy.xml
SIZE: 951
D:"javaGizmos"jakarta-tomcat-4.0.1"webapps"HttpServerSideApp"D:"temp"academy.xml
The browser displayed the following message: “The requested resource (D:"javaGizmos"jakarta-tomcat-4.0.1"webapps"HttpServerSideApp"D:"temp"academy.xml (The filename, directory name, or volume label syntax is incorrect)) is not available.”
This contrasting behavior on different browsers can cause problems. One workaround that I found in an article at http://www.onjava.com/pub/a/onjava/2003/06/25/commons.html is to first create a file reference with whatever is supplied by the getName method and then create a new file reference using the name returned by the earlier file reference. Therefore, you can insert the following code to have your code work with both browsers (I wonder who the guilty party is…blaming Microsoft is always the easy way out)
File tempFileRef = new File(fi.getName());
File fNew = new File(application.getRealPath("/"),tempFileRef.getName());
In this section, you uploaded files using a standard HTML form mechanism. However, often a need arises to be able to upload files from within your jsp servlet ejb code, without any browser or form coming into the picture. In the next section, you will look at HttpClient-based file upload.
Using HttpClient-Based FileUpload
Earlier in the article you saw
some of the capabilities of the HttpClient component. One capability I
did not cover was its ability to send multipart requests. In this
section, you will use this capability to upload a few files to the same
JSP that you used for uploads using HTML.
The class org.apache.commons.httpclient.methods.MultipartPostMethod provides the multipart method capability to send multipart-encoded forms, and the package org.apache.commons.httpclient.methods.multipart has the support classes required. Sending a multipart form using HttpClient is quite simple. In the code in Listing 1-3, you send three files to ProcessFileUpload.jsp.
Listing 1-3. HttpMultiPartFileUpload.java
package com.commonsbook.chap9;
import jsp servlet ejb .io.File;
import jsp servlet ejb .io.IOException;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.MultipartPostMethod;
public class HttpMultiPartFileUpload {
private static String url =
"http://localhost/yaoliang/ProcessFileUpload.jsp";
public static void main(String[] args) throws IOException {
HttpClient client = new HttpClient();
MultipartPostMethod mPost = new MultipartPostMethod(url);
client.setConnectionTimeout(8000);
// Send any XML file as the body of the POST request
File f1 = new File("D:/students.xml");
File f2 = new File("D:/demy.xml");
File f3 = new File("D:/demyRules.xml");
System.out.println("File1 Length = " + f1.length());
System.out.println("File2 Length = " + f2.length());
System.out.println("File3 Length = " + f3.length());
mPost.addParameter(f1.getName(),f1.getName(), f1);
mPost.addParameter(f2.getName(), f2.getName(), f2);
mPost.addParameter(f3.getName(), f3.getName(),f3);
FilePart part1 = new FilePart("file1",file);
FilePart part2 = new FilePart("file2",file);
FilePart part3 = new FilePart("file3",file);
mPost.addPart(part1);
mPost.addPart(part2);
mPost.addPart(part3);
int statusCode1 = client.executeMethod(mPost);
System.out.println("statusLine>>>" + mPost.getStatusLine());
mPost.releaseConnection();
}
}
In this code, you just add the files as parameters and execute the method. The ProcessFileUpload.jsp file gets invoked, and the output is as follows:
Content Type =multipart/form-data; boundary=----------------31415926535897932384
6
NAME: students.xml
SIZE: 279
D:"javaGizmos"jakarta-tomcat-4.0.1"webapps"HttpServerSideApp"students.xml
NAME: academy.xml
SIZE: 951
D:"javaGizmos"jakarta-tomcat-4.0.1"webapps"HttpServerSideApp"academy.xml
NAME: academyRules.xml
SIZE: 1211
D:"javaGizmos"jakarta-tomcat-4.0.1"webapps"HttpServerSideApp"academyRules.xml
Thus, file uploads on the server side become quite a simple task if you are using the Commons FileUpload component.
我们不可能列举所 有可能的固Q我们会针对几种最常见的问题进行处理。当然了Q正如前面说到的Q如果我们自׃用java.net.HttpURLConnection? 搞定q些问题是很恐怖的事情Q因此在开始之前我们先要介l一下一个开放源码的目Q这个项目就是Apache开源组l中的httpclientQ它隶属? Jakarta的commons目Q目前的版本?.0RC2。commons下本来已l有一个net的子目Q但是又把httpclient单独提出 来,可见http服务器的讉Kl非易事?/span>
Commons-httpclient 目是专门设计来简化HTTP客户端与服务器进行各U通讯~程。通过它可以让原来很头疼的事情现在L的解冻I例如你不再管是HTTP或者HTTPS? 通讯方式Q告诉它你想使用HTTPS方式Q剩下的事情交给httpclient替你完成。本文会针对我们在编写HTTP客户端程序时l常到的几个问题进 行分别介l如何用httpclient来解军_们,Z让读者更快的熟悉q个目我们最开始先l出一个简单的例子来读取一个网늚内容Q然后@序渐q解 x前进中的所有问题?/span>
1Q?d|页(HTTP/HTTPS)内容
下面是我们给出的一个简单的例子用来讉K某个面
/*
* Created on 2003-12-14 by Liudong
*/
package http.demo;
import java.io.IOException;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.*;
/**
* 最单的HTTP客户?用来演示通过GET或者POST方式讉K某个面
* @author Liudong
*/
public class SimpleClient {
public static void main(String[] args) throws IOException
{
HttpClient client = new HttpClient();
//讄代理服务器地址和端?nbsp;
//client.getHostConfiguration().setProxy("proxy_host_addr",proxy_port);
//使用GETҎQ如果服务器需要通过HTTPSq接Q那只需要将下面URL中的http换成https
HttpMethod method = new GetMethod("http://java.sun.com");
//使用POSTҎ
//HttpMethod method = new PostMethod("http://java.sun.com");
client.executeMethod(method);
//打印服务器返回的状?/span>
System.out.println(method.getStatusLine());
//打印q回的信?/span>
System.out.println(method.getResponseBodyAsString());
//释放q接
method.releaseConnection();
}
}
在这个例子中首先创徏一? HTTP客户?HttpClient)的实例,然后选择提交的方法是GET或者POSTQ最后在HttpClient实例上执行提交的ҎQ最后从所? 择的提交Ҏ中读取服务器反馈回来的结果。这是使用HttpClient的基本流E。其实用一行代码也可以搞定整个请求的q程Q非常的单!
2Q?以GET或者POST方式向网|交参?/p>
其实前面一个最单的CZ中我们已l介l了如何使用GET或者POST方式来请求一个页面,本小节与之不同的是多了提交时讑֮面所需的参敎ͼ我们 知道如果是GET的请求方式,那么所有参数都直接攑ֈ面的URL后面用问号与面地址隔开Q每个参数用&隔开Q例如:http://java.sun.com?name=liudong&mobile=123456Q但是当使用POSTҎ时就会稍微有一点点ȝ。本节的例子演C向如何查询手机L所在的城市Q代码如下:
/*
* Created on 2003-12-7 by Liudong
*/
package http.demo;
import java.io.IOException;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.*;
/**
* 提交参数演示
* 该程序连接到一个用于查询手机号码所属地的页?/p>
* 以便查询LD?330227所在的省䆾以及城市
* @author Liudong
*/
public class SimpleHttpClient {
public static void main(String[] args) throws IOException
{
HttpClient client = new HttpClient();
client.getHostConfiguration().setHost("www.imobile.com.cn", 80, "http");
HttpMethod method = getPostMethod();//使用POST方式提交数据
client.executeMethod(method);
//打印服务器返回的状?/p>
System.out.println(method.getStatusLine());
//打印l果面
String response =
new String(method.getResponseBodyAsString().getBytes("8859_1"));
//打印q回的信?/p>
System.out.println(response);
method.releaseConnection();
}
/**
* 使用GET方式提交数据
* @return
*/
private static HttpMethod getGetMethod(){
return new GetMethod("/simcard.php?simcard=1330227");
}
/**
* 使用POST方式提交数据
* @return
*/
private static HttpMethod getPostMethod(){
PostMethod post = new PostMethod("/simcard.php");
NamePair simcard = new NamePair("simcard","1330227");
post.setRequestBody(new NamePair[] { simcard});
return post;
}
}
在上面的例子中页?a target="_blank">http://www.imobile.com.cn/simcard.php需要一个参数是simcardQ这个参数gؓ手机LD,x机号码的前七位,服务器会q回提交的手机号码对应的省䆾、城市以及其他详l信息。GET的提交方法只需要在URL后加入参C息,而POST则需要通过NamePaircL讄参数名称和它所对应的?/p>
3Q?处理面重定?/p>
在JSP/Servlet~程中response.sendRedirectҎ是使用HTTP协议中的重定向机制。它与JSP中的< jsp:forward …>的区别在于后者是在服务器中实现页面的跌{Q也是说应用容器加载了所要蟩转的面的内容ƈq回l客LQ而前者是q回一个状态码Q这些状态码 的可能D下表Q然后客Ld需要蟩转到的页面的URLq新加载新的页面。就是这样一个过E,所以我们编E的时候就要通过 HttpMethod.getStatusCode()Ҏ判断q回值是否ؓ下表中的某个值来判断是否需要蟩转。如果已l确认需要进行页面蟩转了Q那么可 以通过dHTTP头中的location属性来获取新的地址?/p>
maxConnectionsPerHost | 每个L的最大ƈ行链接数Q默认ؓ2 |
maxTotalConnections | 客户端dƈ行链接最大数Q默认ؓ20 |
Features | nogoop | Sun JRE < 1.4.2 | Sun JRE 1.4.2 | Innovation | Apache/Jakarta |
s | X | X | |||
plug compatible | X | X | X | X | [partial] |
true request output stream | X | X | |||
true response input stream | X | X | X | ||
connection keep alive | X | X | X | X | X |
connection pool throttling | X | X | |||
connection/request timeout | X | X [uns] | X | X | |
idle connection timeout | X | X | |||
pipelining of requests | X | ||||
alternate DNS resolution (dnsjava) | X | ||||
SSL | X | X | X | X | X |
basic authentication | X | X | X | X | X |
digest authentication | X | X | X | X | X |
NTLM authentication | X | [Windows only] | X | ||
proxy authentication | X | X | X | X | X |
minimum JRE version | 1.2 | 1 | 01q???/td> | 1.2 | 1.2 |
price | $499 | free | free | free | free |
source available | X | X | X | ||
diagnostic tracing | X | X | X | ||
actively supported | X | X | X | X | |
fix turnaround | fast | slow | slow | none | medium |
license | purchase | Sun JRE | Sun JRE | LGPL | Apache |